Spread Firefox Affiliate Button

Pages

Photo Friday – Black

Black Pear

My first Photo Friday shot in a loooong time.

Just messing around with off-camera flash, trying to learn how to control the highlights and shadows.

100 Push Ups: Week 4, Day 2 – FAIL!

So I didn’t even come close to finishing the required sets last night.

I was supposed to do 25, 29, 25, 25, >= 36. 36! That’s crazy talk!

I only managed 25 or 26 on the last set before collapsing on the floor. I think tomorrow I’ll re-do Week 3, Day 3’s routine, and then make another attempt at Week 4 next week.

100 Push Ups: Week 4, Day 1

I finished week 3 of the challenge without too much difficulty. Day 3 of week 3 was 22, 30, 20, 20, >= 28 and I managed 30 in the final set.

Today was much more difficult. The plan for today was: 21, 25, 21, 21, >= 32. Wow, the final two sets were rough. I’m not sure if my 32nd push up of the last set could really be called a push up, one arm wasn’t cooperating, and I practically fell over trying to complete it…I’ll give myself the benefit of the doubt and see how the rest of the week turns out. I have a feeling I may be repeating this week!

python reload: danger, here be dragons

At Mozilla, we use buildbot to coordinate performing builds, unit tests, performance tests, and l10n repacks across all of our build slaves.

There is a lot of activity on a project the size of Firefox, which means that the build slaves are kept pretty busy most of the time.

Unfortunately, like most software out there, our buildbot code has bugs in it. buildbot provides two ways of picking up new changes to code and configuration: ‘buildbot restart’ and ‘buildbot reconfig’.

Restarting buildbot is the cleanest thing to do: it shuts down the existing buildbot process, and starts a new one once the original has shut down cleanly. The problem with restarting is that it interrupts any builds that are currently active.

The second option, ‘reconfig’, is usually a great way to pick up changes to buildbot code without interrupting existing builds. ‘reconfig’ is implemented by sending SIGHUP to the buildbot process, which triggers a python reload() of certain files.

This is where the problem starts.

Reloading a module basically re-initializes the module, including redefining any classes that are in the module…which is what you want, right? The whole reason you’re reloading is to pick up changes to the code you have in the module!

So let’s say you have a module, foo.py, with these classes:

class Foo(object):
    def foo(self):
        print "Foo.foo"
 
class Bar(Foo):
    def foo(self):
        print "Bar.foo"
        Foo.foo(self)

and you’re using it like this:

>>> import foo
>>> b = foo.Bar()
>>> b.foo()
Bar.foo
Foo.foo

Looks good! Now, let’s do a reload, which is what buildbot does on a ‘reconfig’:

>>> reload(foo)
<module 'foo' from 'foo.pyc'>
>>> b.foo()
Bar.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/catlee/test/foo.py", line 13, in foo
    Foo.foo(self)
TypeError: unbound method foo() must be called with Foo instance as first argument (got Bar instance instead)

Whoops! What happened? The TypeError exception is complaining that Foo.foo must be called with an instance of Foo as the first argument. (NB: we’re calling the unbound method on the class here, not a bound method on the instance, which is why we need to pass in ’self’ as the first argument. This is typical when calling your parent class)

But wait! Isn’t Bar a sub-class of Foo? And why did this work before? Let’s try this again, but let’s watch what happens to Foo and Bar this time, using the id() function:

>>> import foo
>>> b = foo.Bar()
>>> id(foo.Bar)
3217664
>>> reload(foo)
<module 'foo' from 'foo.pyc'>
>>> id(foo.Bar)
3218592

(The id() function returns a unique identifier for objects in python; if two objects have the same id, then they refer to the same object)

The id’s are different, which means that we get a new Bar class after we reload…I guess that makes sense. Take a look at our b object, which was created before the reload:

>>> b.__class__
<class 'foo.Bar'>
>>> id(b.__class__)
3217664

So b is an instance of the old Bar class, not the new one. Let’s look deeper:

>>> b.__class__.__bases__
(<class 'foo.Foo'>,)
>>> id(b.__class__.__bases__[0])
3216336
>>> id(foo.Foo)
3218128

A ha! The old Bar’s base class (Foo) is different than what’s currently defined in the module. After we reloaded the foo module, the Foo class was redefined, which is presumably what we want. The unfortunate side effect of this is that any references by name to the class ‘Foo’ will pick up the new Foo class, including code in methods of subclasses. There are probably other places where this has unexpected results, but for us, this is the biggest problem.

Reloading essentially breaks class inheritance for objects whose lifetime spans the reload. Using super() in the normal way doesn’t even work, since you usually refer to your instance’s class by name:

class Bar(Foo):
    def foo(self):
        print "Bar.foo"
        super(Bar, self).foo()

If you’re using new-style classes, it looks like you can get around this by looking at your __class__ attribute:

class Bar(Foo):
    def foo(self):
        print "Bar.foo"
        super(self.__class__, self).foo()

Buildbot isn’t using new-style classes…yet…so we can’t use super(). Another workaround I’m playing around with is to use the inspect module to get at the class hierarchy:

def get_parent(obj, n=1):
    import inspect
    return inspect.getmro(obj.__class__)[n]
 
class Bar(Foo):
    def foo(self):
        print "Bar.foo"
        get_parent(self).foo(self)

100 Push Ups: Week 3, Day 2…

Ok, so I fell off the wagon for a bit.

But I’m back on track now!

I did manage to do day 1 of week 3 last week…but the Real Life took over, late nights working or various other activities, and before I know it it’s the next Monday and my body is screaming for rest after spending most of Sunday installing a garage door opener.

So, this is my second attempt at week 3.

I managed day 1 with little problems: required sets were 14, 18, 14, 14, >= 20, and I managed 21 on the last set.

Today was much more challenging: 20, 25, 15, 15, >= 25. I just barely managed to finish the last set. I just realized that’s 100 push ups total today!

When craziness wraps around… : technovelty

From When craziness wraps around…:

A common trick years ago was to set up your routing tables and then have PID 1 exit so the kernel paniced, because the paniced kernel would continue to route packets with _no_userspace_running_. Darn hard to hack a system like that.

That’s awesome :) Better get your routing tables right the first time though!

100 Push Ups: Exhaustion Test

After finishing week 2 of the program you’re supposed to do an exhaustion test…do as many push ups as you can with no break.

I had a pretty busy weekend, so didn’t get around to doing my test until tonight. I managed to complete 35 push ups! Yay me! This means I can continue on to week 3.

100 Push Ups: Week 2, Day 3

Yesterday I finished week 2 of the push up challenge.

The required sets were: 16, 17, 14, 14, >= 20 with a 2 minute rest in between. I just barely managed to finish 20 in the last set.

The next step in the challenge is to do an exhaustion test: do as many push ups as you can in a row with no rest. This determines what how your sets in the next few weeks will be organized.

My first exhaustion test was back before week 1 started, and I managed 23 push ups.

I’m hoping to do at least 30 now that I have a few weeks under my belt…but we’ll see how things go :)

100 Push Ups: Week 2, Day 2

Required: 14, 16, 12, 12, at least 17 w/ 90 second rest

Did: 14, 16, 12, 12, 20

100 Push Ups: Week 2, Day 1

Yesterday I started the second week of the 100 Push Up challenge.

I needed to complete 5 sets of 14, 14, 10, 10 and max (at least 15) push ups, with a minute rest in between. I did manage to finish all 5 sets, with the minimum 15 push ups on the last set.

This was much more difficult than the last day of last week, probably because of the shorter rest period. My abs were also pretty sore last night after doing the push ups. I can see how this challenge is going to be…challenging :)

I’ll do day 2 of week 2 tomorrow.