[01:41:39] ** rdmurray has left IRC ("User disconnected") [02:42:19] ** gpciceri has joined us [07:46:38] ** vlado has joined us [08:42:04] ** gpciceri has left IRC (Remote closed the connection) [09:30:44] ** vlado has left IRC (Read error: 104 (Connection reset by peer)) [09:30:46] ** vlado_ has joined us [10:13:54] ** rdmurray has joined us [10:24:25] ** vlado_ has left IRC ("ChatZilla 0.9.52B [Mozilla rv:1.6/20040113]") [10:40:27] ** vlado has joined us [12:07:54] vlado is now known as vlado|away [13:24:01] <_jpl_> mornin', all [13:55:51] ** vlado|away has left IRC (Read error: 60 (Operation timed out)) [17:59:24] good afternoon [18:00:10] afternoon [18:00:18] Evening for me, actually [18:00:47] well 5:00 pm, so quasi evening [18:19:48] <_jpl_> also dann, guten abent [18:26:18] we need a smarter bot [18:26:20] * Maniac codes one [18:32:02] <_jpl_> Will it be maniacal? [18:36:06] but of course [18:36:27] i expect the first entry into irc-space to be sometime in q1-05 [18:36:36] it will undergo months of planning [18:36:50] it will be the first peak 1.0 app [18:38:30] <_jpl_> Where will you hold the release party? [18:38:45] irc? [18:39:00] <_jpl_> Of course. Where else. [18:39:04] i tend to plan stuff for months and never actually do them [18:39:33] although i do use my jabber bot alot (it's dictionary and spelling plugins) [18:40:10] no peak emails today (either cvs commits or regular) i'm in withdrawl [18:42:36] <_jpl_> I'll try to find more bugs. [18:44:06] i think he's busy [18:44:12] i'll ask some dumb questinos [18:44:15] er questions [18:44:37] * Maniac considers actually writing an irc bot [18:44:54] _jpl_, do you have a weblog (i'd guess not) [18:44:56] ? [18:46:54] <_jpl_> No, but coincidentally I've been thinking for the last couple of days of starting one. [18:49:14] I've thought about doing that a couple times, but I keep getting stuck on software issues. I keep wanting to fix up my website for real, and it never happens :) [18:49:58] <_jpl_> I know what you mean. [18:50:46] <_jpl_> Though I did find some decent Pythonic blog software when I looked around recently. [18:51:08] Hmm. cgi script? [18:51:09] _jpl_, which one? (i use syncato) [18:52:12] rdmurray, where's your website? [18:52:43] www.bitdance.com [18:52:48] It's pretty dumb, right now. [18:52:55] <_jpl_> There was PyDS I think it was called [18:53:03] <_jpl_> and, uh, pybloxsom? [18:53:29] yeah i used to use pybloxsom [18:53:35] PyDS is probably good [18:53:38] <_jpl_> I never got on the blog bandwagon while it was getting ultrapopular, so I'm pretty out of the loop on what's out there. [18:53:40] pybloxsom is a cgi [18:53:54] there's not that much in terms of python [18:54:01] syncato, pyblosxom, PyDS [18:54:05] pretty much it [18:54:12] syncato has 3 or 4 users :) [18:54:30] <_jpl_> My ISP doesn't do mod_python or FastCGI, so I'd have to do a CGI. Or move to python-hosting.com, which I've been considering. [18:54:42] pyblosxom does not allow you to setup multiple categories per post so i switched [18:55:00] <_jpl_> PyDS looked nice, but I never got around to actually trying it out. [18:55:05] <_jpl_> ah [18:55:12] <_jpl_> I'd need multiple categories for sure. [18:55:13] i don't know if you can use a cgi with PyDS either [18:55:26] fwiw blosxom doesn't do multiple categories per post [18:55:34] <_jpl_> Well, if I went the PyDS route I'd probably publish to one of the big blog sites. [18:55:43] ah yes [18:55:45] good point [18:55:49] go for it [18:55:52] :) [18:55:59] * Maniac has a useless blog already :) [19:00:35] I've got way too many projects I want to work on. [19:01:05] And now my old work and current biggest consluting customer wants a bunch of my hours in feb and march. [19:01:24] heh, that's a good freudian typo. [19:01:40] <_jpl_> Indeed [19:02:57] ha consluting [19:04:00] i need a good book to read [19:04:09] How old are you? [19:04:53] (My recommendation is age related :) [19:05:00] Or I could recommend some SF. [19:07:03] 12? [19:07:18] ok 29 or so [19:07:50] (i was wondering what you would recommend to a kid...) [19:07:53] either way, likely too young for my current fave read. (It's about getting through your midlife crisis) [19:08:10] yeah, too young for that :) [19:08:25] <_jpl_> Read _Midnight's Children_ [19:08:46] salmon rushdie [19:08:55] <_jpl_> Correct [19:09:01] <_jpl_> Salman, though [19:09:22] <_jpl_> (pronounced "sull-mahn") [19:09:22] intentional misspelling [19:09:44] I highly recommend "American Gods" by Neil Gaiman. [19:10:24] <_jpl_> _The Sheltering Sky_ [19:10:44] <_jpl_> _The Fall_ [19:11:34] <_jpl_> _Don Quixote_ [19:11:55] ok how about some lighter reading :) [19:12:18] "The Pragmatic Programmer" :) [19:12:24] <_jpl_> That's a good one [19:12:45] <_jpl_> Maniac: That *is* my lighter reading list. [19:13:08] If you like SF, "1632" by Eric Flint is fun. [19:13:18] well, alternate history. [19:14:14] Hmm. Time to make some popcorn. [19:14:17] ok got pragmatic programmer to 'review' [19:15:10] http://safari.oreilly.com/JVXSL.asp?x=1&mode=section&sortKey=rank&sortOrder=desc&view=book&xmlid=0-201-61622-X&open=false&g=&srchText=pragmatic+programmer&code=&h=&m=&l=1&catid=&s=1&b=1&f=1&t=1&c=1&u=1&r=&o=1&page=0 [19:15:32] i assume that's it [19:16:59] yep [19:17:50] * Maniac starts reading [20:26:21] ** pje has joined us [20:26:27] * pje waves [20:26:38] * pje is now finally fixing JPL's bugs [20:26:43] 'lo [20:26:45] Er, well, my bugs, really. :) [20:26:54] jpl will be glad to hear that, I'm sure :) [20:26:57] Been *really* snowed under at work this week. [20:27:28] Mostly with nontech stuff, alas. People stuff, which I find exceedingly stressful. [20:27:43] Ah, yeah. [20:27:52] my sympathies. [20:27:56] On the bright side, almost half of it was because I was asked to comment on/participate in other projects. [20:28:03] IOW, my input was wanted and desired. [20:28:13] On the other half I was not so fortunate. [20:28:20] But I'm back to coding now, yay! [20:28:25] :) [20:29:04] Speaking of which... when's your next checkin, JPL? :) [20:32:16] * pje checks in the bug fixes [20:32:36] Is there an email list for checkin messages? [20:32:53] Or did I already ask that... [20:32:56] <_jpl_> Hi Phillip [20:33:07] source-changes@eby-sarna.com [20:33:13] thanks [20:33:27] Click on 'Revision History' on peak.telecommunity.com [20:33:57] <_jpl_> Phillip, what size workplace do you work in? [20:33:58] Then "more info about this list" to subscribe. [20:34:25] I dunno... at one point the company had something like 3600 people. [20:34:38] It also depends on whether you include the parent company. :) [20:34:40] <_jpl_> Ah, that's pretty large. [20:36:35] <_jpl_> Is Python used quite a bit there? [20:37:18] Heh. [20:37:19] No. [20:37:43] <_jpl_> You've had to work at getting management to except it, then? [20:37:53] Oh no, that's not the issue at all. [20:38:21] Not even *an* issue, really. Hasn't been an issue of any consequence for almost half a decade. [20:39:02] It's just that there are lots and lots of larger development groups in the company, and they are predominantly Perl, C, or Java. [20:39:39] <_jpl_> Likewise here, where the "real" development teams are mostly C++ and Perl. [20:42:40] * pje is beginning the great I Can't Believe It's Not Threads renaming [20:43:19] Sheesh. I probably should've shamed Ty into doing this; there's a *lot* of docstrings to be rewritten, and parameter names to be changed, not just class/interface names. :( [20:50:46] <_jpl_> ... when's my next checkin? To where? [20:51:05] peakplace... Junction examples using peak.events [20:51:26] http://peakplace.tigris.org/source/browse/peakplace/src/junction/examples/simple/ [20:51:30] to be precise. :) [20:52:16] <_jpl_> Right [20:52:30] <_jpl_> Soonish [20:53:03] <_jpl_> Actually, I should probably wait until after the great renaming. [20:54:14] I had a feeling you'd say that. :) [20:54:27] Really, it's not that great in the code. It's mostly docs that are suffering. [20:54:34] Or me that's suffering through changing them, really. [20:56:09] <_jpl_> I realized the other day that Junction needs distributed registries. [20:57:37] <_jpl_> ...which would be kept up to date with all participants through pub/sub. [20:57:57] Interesting. [20:58:35] <_jpl_> I was taking another look at Spread the other day and thinking about how to integrate it into Junction. [20:59:38] <_jpl_> They've handled a lot of the harder things that I wanted Junction to be able to do. But then one of the main ideas is to keep it transport neutral as much as possible, so I'd still need to do most of that work. [20:59:50] * pje sighs. Only 111 occurrences of "thread" left to look at... [21:00:40] Well, you can always design around event sources that you simply require to have certain transport properties, such as reliability, ordering, etc. [21:01:06] <_jpl_> I'm also going to rethink a few things so that Junction can use peak.events as much as possible. [21:02:31] I've been designing an SMTP client component for peak.events... [21:03:06] I expect it will have a sendMessage() method that returns an event source or sources that will tell you when (if) the message is sent. [21:03:33] Or, maybe the sources will be attached to a Message object, e.g. message.deliveryStatus [21:03:48] <_jpl_> Have you considered the possibility of "events" being objects (which implement, say, IEvent)? [21:03:58] So, you just pass in the message after subscribing to its return status. [21:04:18] JPL: no. I want it to be convenient to use ordinary objects and values as events. [21:04:35] If a particular source wants to more precisely define what it sends, that's of course quite cool. [21:05:05] * _jpl_ nods. [21:05:06] But peak.events itself will never dictate what an "event" consists of, even if other PEAK frameworks end up creating more featureful event interfaces. [21:05:27] That's what makes it a microkernel. :) [21:07:56] <_jpl_> Right, so I could create custom event sources which pass, say, Message objects. [21:08:25] Yep. [21:08:33] <_jpl_> Where Messsage will have a uuid, timestamp, source, destination, message, reply, etc. [21:08:35] You don't even need custom ones, which is sort of the point. :) [21:08:57] You can take an "off the shelf" Distributor or Broadcaster and pass your Message object to it. [21:09:06] <_jpl_> True, things like Value don't care what you put in them. [21:09:28] Well, Value expects that you can perform equal/not equal comparisons on what you put in it. [21:09:45] Other than that, it's a free for all. :) [21:09:50] <_jpl_> Which Python lets you do with instance objects. [21:10:29] Yep, and the default implementation is adequate, which compares based on object identity. [21:10:51] But, you usually wouldn't put something like a Message in a Value, anyway. [21:11:13] What would that value be, "this is the message I'm working on"? It doesn't make any sense except in say a GUI context. [21:11:35] Where you might then use some sort of two-way derived values to edit parts of whatever the current message you're editing is. [21:13:27] * pje is down to about 62 "thread" references now [21:13:37] <_jpl_> Right... I suppose the use case will be more like "yield junction.call('someservice', 'somemethod', ...); response=events.resume()" [21:14:22] Yep. [21:14:41] I'm really glad "task" is a shorter word than "thread", or there'd be lots of line wrapping to deal with. [21:19:18] ...and the tests pass again. Yeeha. [21:19:42] <_jpl_> Currently junction.callServiceMethod returns a Deffered, so yielding already works through the adapter. To move away from being so Twisted-centric, I'll want to return some other type of event source. I take it I can just return Broadcaster instances? [21:20:03] Yep, as long as you want them to be Broadcasters instead of Distributors. [21:20:28] (And you probably do.) [21:20:52] Although, if you're using Deferreds, really a Value is the closest thing conceptually. [21:21:12] Well, actually I guess a Deferred is like a Value with the callback behavior of a Condition. [21:21:50] I imagine there actually is a place for having a 'OneShot' event type that is expected to fire once, and whenever you add a callback you just get the value. [21:22:15] Like a deferred without any chaining or (ugh) mutability. :) [21:22:16] <_jpl_> It can be pretty handy. [21:22:51] <_jpl_> Which part of a Deferred is mutable? [21:22:56] The value. [21:23:11] Callbacks change it, and the changed value is passed to the next callback. [21:23:12] <_jpl_> I thought it couldn't change once it's been fired. [21:23:24] <_jpl_> Oh, you mean in a callback chain. [21:23:41] Yeah, a deferred is sort of like a pipeline. [21:24:20] However, in peak.events, there are plenty of other ways to pipeline, and you don't need that kind of chaining in order to do simple sequential computations, either. [21:24:47] <_jpl_> Yes, and that functionality has been pretty useful at times, but that's mostly because of the Twisted model (having no other event source than Deferreds). [21:25:20] So, if I made a "OneShot", it would be sort of like a Broadcaster that you could only call 'send()' on once, and if 'send()' was already called, then adding callbacks would get them called immediately. [21:25:22] <_jpl_> That's what I figured, but it would be nice to see some examples of doing so with peak.events. [21:28:13] * pje checks in the renaming [21:28:25] <_jpl_> Wait, you don't need that kind of chaining since the generator functions progress linearly (at least from the programmer's perspective)... [21:28:38] Right. [21:28:53] Of course, you can used derived values if you need to. [21:29:22] er, use. [21:29:44] And derived values change whenever their base value changes, too. [21:29:50] It's not a one-time computation. [21:31:25] Indeed, you can do functional composition on events in a useful way too... [21:31:27] e.g. [21:31:33] def timesTwo(source): [21:31:33] <_jpl_> I'm very glad to be able to write code again which doesn't have to jump all over the place to implement a simple idea. [21:31:47] yield source; yield events.resume()*2 [21:32:14] def asString(source): [21:32:24] yield source; yield str(events.resume()) [21:32:40] def printDoubledString(source): [21:33:03] er... [21:33:07] whoops. [21:33:14] That doesn't actually work the way I was thinking. :) [21:33:40] I need to make tasks event sources, and procedures adaptable to tasks, and then it will work. :) [21:34:08] And then you could do: [21:34:23] yield asString(timesTwo(source)); print events.resume() [21:35:09] Ah well. [21:36:40] <_jpl_> So tasks don't yet return the value of their last yield? [21:37:05] Well, they can't "return" it. [21:37:24] Tasks return to an event source's calling them back, so they return 'True'. [21:37:43] But if a task were an event source itself, it could yield value(s), yes. [21:39:48] * pje wonders how long it would take to implement... [21:49:46] Hm. Not long at all, it appears. :) [21:59:36] i need to port PEAK to C# [21:59:53] * pje shudders [22:00:15] :P [22:00:36] At the thought of the effort involved. [22:00:51] * Maniac shoulder at the thought of effort [22:00:57] shudders even [22:01:27] _jpl_ wants an irc bot for peak that has a 'seen' command [22:05:34] * Maniac nudges pje [22:05:49] * pje raises an eyebrow [22:06:01] i guess i have to do it :) [22:06:14] i'm planning a short release cycle [22:06:24] should have a prototype by 1st Q 05 [22:07:55] <_jpl_> Now that we can make Twisted more civilized through peak.events, you should be able to come up with something pretty quickly, right? [22:15:10] oh, well i don't know how to use that yet [22:15:29] i'm trying to figure out how to use my existing code right now (whilst watching TV) [22:15:57] Ha. It works... [22:15:59] def testComposition(self): [22:15:59] def timesTwo(source): [22:15:59] yield source; yield events.resume()*2 [22:15:59] def asString(source): [22:15:59] yield source; yield str(events.resume()) [22:16:00] def strDouble(source): [22:16:02] yield asString(timesTwo(source)); yield events.resume() [22:16:04] def doubleStr(source): [22:16:06] yield timesTwo(asString(source)); yield events.resume() [22:16:10] data = [1,2,3,5,8,13]; v = events.Value() [22:16:14] for item in data: [22:16:16] log = [] [22:16:18] task = events.Task(self.simpleGen(log, strDouble(v), NOT_GIVEN)) [22:16:20] v.set(item); self.assertEqual(log,[str(item*2)]) [22:16:22] for item in data: [22:16:24] log = [] [22:16:26] task = events.Task(self.simpleGen(log, doubleStr(v), NOT_GIVEN)) [22:16:28] v.set(item); self.assertEqual(log,[str(item)*2]) [22:17:02] Now you can write pipeline iterators like this: [22:17:05] while True: [22:17:16] yield baseSource; value = events.resume() [22:17:24] if value is NOT_GIVEN: break [22:17:36] yield doSomethingWithValue [22:18:21] NOT_GIVEN is the sentinel value provided when a nested iterator finishes. [22:18:59] And tasks are event sources. [22:19:07] Just gotta figure out how to *document* all this, now. :) [22:23:55] Wow, PEAK's up to 611 tests, now. I think that doesn't even count Zope support tests. [22:31:11] * pje checks in the code [22:31:16] <_jpl_> Nice work on tasks as event sources. [22:31:21] <_jpl_> That was quick. :) [22:31:37] That's three checkins in the last few hours. [22:31:46] Like I said, it's good to be coding again. [22:33:24] <_jpl_> The "yield events.resume()" seems a little strange at first. [22:33:27] My next big thing is likely to be a "socketpair" emulation. (But not tonight!) [22:34:21] I want to create "mock sockets" that can be used to test higher-level protocols and things, without using real sockets. [22:34:55] They will be like a loopback, where 'accept()' on one matches 'connect()' on the other, send() on one goes to recv() on the other, and so on. [22:35:05] And vice versa, of course. [22:35:34] And then they'll be packaged with a dummy 'select()' function, that'll be wrapped into a TestSelector for doing peak.events tests. [22:36:13] So, it should be possible to e.g. test an SMTP client component by writing tests that do things on the "other end" of the socket the client thinks it's connecting to. [22:36:32] <_jpl_> peak.binding makes tests far easier to write in general, since you can easily supply fake components that provide data to the component(s) you're testing. It's enabled me to write test over the last few days that would have resulted in extreme ugliness without PEAK. [22:37:04] Well, that assumes you've parameterized what you need to test. [22:37:19] Writing the tests first tends to encourage you to write things in a testable way. :) [22:37:45] But that's why I'm planning to create "mockets" (mock sockets), anyway. [22:38:14] I love things that make writing tests easier :) [22:39:42] I don't want to be stuck in a situation where the only way to test socket-based protocols is to actually connect to something. [22:40:05] Yeah, that can be a real pain. [22:40:58] Now if I could just find a way to "mock" a 'fork()' operation, I'd be in good shape for adding tests to the 'supervisor' tool. :) [22:41:55] One nice thing about mocking up sockets, is that it should then be possible to create DDT test documents that describe expected sequences of messages in a client/server conversation. [22:42:24] Which is then a nice document filled with helpful protocol examples. :) [22:43:30] ** pyneak has joined us [22:44:00] I really need to get the full 'ddt.web' server working. I'm planning to make it a 'peak.web' app, serving up directories and directory listings, and using resources.ini files to configure test environments for the subdirectories. [22:44:51] Ideally, for that I should also make it possible to set PYTHONPATH stuff from .ini files. [22:45:20] Or more precisely, to set path prefixes for lazy import operations. [22:46:20] Sooner or later I'll get around to looking at DDT. It sounds great. [22:46:24] So that you can say something like 'lazyModule("foo",pathPrefix=["/bar"])' [22:47:12] And then if there's a way to access that in an .ini file's [Lazy Imports] section, we'll be pretty much set. [22:48:00] There are a few policy issues to work out, though, like what to do if there's already been a lazy import with a different path prefix, or the module is already loaded, that sort of thing. [22:48:28] Plus, the issue of what to do if the module being loaded makes any sys.path changes of its own - we can't just put back sys.path how we found it. [22:50:07] I'm also not 100% positive that it should be a sys.path *prefix*, either, as opposed to a suffix. [22:50:39] Obviously, the whole thing is still a bit vague in my mind. :) [22:51:35] Well, I better get going for tonight, and rest up for the coding ahead. :) [22:51:59] :) [22:52:05] Laters, all. [22:52:18] ** pje has left IRC ("Client exiting") [23:00:55] <_jpl_> I need to run, too. Bye all. [23:02:37] ** _jpl_ has left IRC ("Leaving")