| userpic factory |
[Mar. 29th, 2006|06:08 pm] |
Please help beta-test the userpic factory:
http://www.livejournal.com/editpics-beta.bml
It lets you upload any JPEG and make a userpic out of it, using some fancy JavaScript and some fun stuff on the backend (we're finally using gearman in production!)
Please report any bugs or confusion. |
|
|
| Bugs, Meetings, Testing |
[Jul. 10th, 2005|11:46 pm] |
So the combination of like four of us teamed up to contribute seemingly benign patches which in combination produced a bug that was caught and fixed within hours of release.
It was suggested that we have a post-mortem to discuss it, but I, being stubborn, said I wouldn't be attending, since we'd already had a suitable (I thought) post-mortem with the developers involved the night of the bug, and we'd recently had a long post-mortem for another unrelated issue that ended up covering tons of stuff, so I thought nothing new could come of this 3rd post-mortem that wasn't already covered in the first two, short of playing the blame game or something.
Ah, but I was wrong.
While I wanted to avoid a meeting and perhaps hack, it appears my time savings argument was fruitless as I've likely spent more time reading/writing emails about the meeting and the issue than the proposed meeting would've taken had I just attended.
So I admit defeat, and in addition to having spent time and my precious wrists/fingers writing emails, I will also be attending the meeting, if only to cut my losses and not type anymore.
But it might be fun as I'd love to discuss writing a test suite to cover the entirety of LiveJournal. Historically I've shunned tests, mostly because anything non-trivial I work with is distributed on lots of machines, deals with timing, and is just generally a bitch to test accurately. Lately, however, I've had success writing test suites of pretty complicated things, like LWPx::ParanoidAgent, OpenID, and just this weekend with Ben, Gearman (which Ben pretty much did).
So I'm warming up to automated testing, especially considering it'd be something the sysadmins could run first to feel better about code being pushed, and there'd be proof in the code repo that a test was or was not written. (which there would then be policy to include)
In conclusion: fun, fun. |
|
|
| Hacking update |
[Jul. 10th, 2005|09:16 am] |
After my nap(s) yesterday, I headed over to btrott's for Zante's and hacking. Lots of commits both before and after midnight.
We double-teamed Gearman, documenting it, rearranging it, and writing a mostly comprehensive test suite for the combination of client, worker, and server. Test suites that vary with timing are fun. And ones that involve forking off a bunch of processes, making them all talk, killing some at the right times, etc.
So overall, very productive.
It's just kinda sad that I have to hack on the weekend to really get in the groove and have a couple straight hours to focus without interruptions. |
|
|
| Data::ObjectDriver |
[Jun. 7th, 2005|09:11 pm] |
Ben somehow tricked me into working on yet another project ... he wants me to adapt their MT ObjectDriver code into something more generic that abstracts away database partitioning, memcaching, etc. And then filtering/joins/etc too.
The end result, as pseudo-planned, will look like a mix of MT/TypePad's ObjectDriver code, plus kinda like Class::DBI, but layered...
Data::ObjectDriver Data::ObjectDriver::Driver Data::ObjectDriver::Driver::Cache Data::ObjectDriver::Driver::DBI Data::ObjectDriver::Driver::DBI::mysql Data::ObjectDriver::Driver::DBI::postgres Data::ObjectDriver::Driver::Paritions Data::ObjectDriver::Proxy Data::ObjectDriver::CachePolicy Data::ObjectDriver::Schema
The Cache one lets you define a cache callbacks for loading/setting/deleting primary keys. (for e.g. memcached). So loads come from cache, else get passed down to a lower-level driver. Sets delete from cache, then get proxied to lower-level driver. The DBI ones lets you connect to databases and do range queries and such, the partition one lets you define a callback that given an object, returns a new driver.
etc. etc.
I've wanted something like for a long time but have been too scared to try. Given that people successfully use Class::DBI and MT/TypePad run on MT's ObjectDriver stuff, it should be fine.... it'll be an interesting project.
The plan is to open source it all (terms of Perl itself), so if it works out, LiveJournal will use it too, and clean up a lot of our data-handling code, hopefully.
But this is like 5 projects down the road. I keep bouncing back and forth. I've recently started working on Gearman again, now that OpenID is settling a bit. |
|
|
| gearman demo; distributed map in Perl |
[Apr. 13th, 2005|11:08 pm] |
We've been talking about writing a distributed job system for awhile now. I'm pretty aware of what's out there, but you know me. (hate everything, picky, etc....)
So Whitaker and I spec'ed this out last week and I got to hacking on it today. Even with on/off interrupted hacking time all day, it works:
-- Multiple job servers track clients and workers. (scales out)
-- Clients hash requests to the "right" job server, or whoever's alive. There is no right job server, but the job server can merge requests if the clients both wanted, so it's beneficial to map the same jobs to the same job servers. That is, if two callers both ask for job "slow_operation_and_big_result" to be done, it's only done once, even if the second client comes in 2 seconds into the computation.
-- Workers on connect announce what job types they're willing to do. Can also unown things.
-- Workers poll all job servers doing a "grab_job" operation. If no jobs, workers announce they're going to sleep, and select on a "noop" wake-up packet from the server if it gets something the worker can do. (job server can't just give out the job, lest there be races between multiple job servers, and you want low-latency: it'd be bad for two job servers to send a request to the same worker when another worker was idle... so all jobservers can do is wake up workers)
-- Clients can submit lots of jobs, get handles for them, and wait for their results (and status updates) in parallel
-- Client can submit a "background" job where a handle is returned, but client isn't subscribed to status notifications. The client just wants it done sometime soon, but it's going away.
-- Job server makes no promises about things getting done eventually, durability, etc. That's all done at different layers. (for instance: for non-background jobs, the client module can be told that the result is idempotent and on failure, it should be retried, the failure hidden from the client)
Anyway... I didn't want to go into all those details, because they're poorly explained. But it works, and one worker process I just wrote registers with the job server and announces it can help do a distributed map for Perl, using Storable.pm's CODE serialization using B::Deparse.
Observe:
sammy:server $ cat dmap.pl
#!/usr/bin/perl
use strict;
use DMap;
DMap::set_job_servers("sammy", "kenny");
my @foo = dmap { "$_ = " . `hostname` } (1..10);
print "dmap says:\n @foo";
sammy:server $ ./dmap.pl
dmap says:
1 = sammy
2 = papag
3 = sammy
4 = papag
5 = sammy
6 = papag
7 = sammy
8 = papag
9 = sammy
10 = papagSo it's like Perl's map, but the computations are spread out all over, and recombined in order.
I can't wait for this to be production-quality so we can do things like parallel DB queries. (I especially love the request merging.) |
|
|