[03:58:23] ** vlado_ has joined us [06:14:04] ** jack-e has joined us [06:14:22] re [06:14:24] * jack-e is really looking forward to peak.events too :))) [07:48:18] ** jack-e has joined us [13:42:07] <_jpl_> Hi M [13:47:25] <_jpl_> Thought of some other 'advantages' of Junction: it keeps track of client connections, and each connected client passes in an IClientController object; so you could query the client list to see who/what is connected and use the client controller objects to ask for status, perform some work on the client, send it some information, etc. [13:48:56] <_jpl_> Also, the recent check-ins include publishing of connection events, so you can subscribe to a subject like "junction.connection.disconnected" to get a notification when your connection to a remote Junction goes down. [13:49:59] <_jpl_> Or "junction.client.login" to get a notification when a client logs in. [13:51:01] <_jpl_> When I get time, there will also be a remote log publisher, so that PEAK log events can be publishable/subscribable like anything else. [14:05:12] <_jpl_> It also decouples method calls from specific objects using a basic 'service' object location mechanism: you lookup a service object by name and then call methods on it. This has at least two advantages: 1) if the service is running in the same process as the client, no network or other external access is required: method calls go directly to the local object. 2) with PB you don't have to worry about writing functionality into your perspective objects, [14:05:45] <_jpl_> Once other endpoint types are developed, services could be at the other end of CORBA, PyRO, XML-RPC, SOAP, etc. connections [15:05:16] do i understand correctly that there is no authorization currently? [15:05:46] if i read the code correctly it's basically letting anyone do anything they want ? [15:06:20] <_jpl_> Yes. [15:06:53] <_jpl_> I've just written down some to-do items in a TODO.txt which I'll check in. v0.6 will have configurable checkers and credential providers. [15:07:59] <_jpl_> (v0.6 will be the next release) [15:08:07] and the service can be arbitrary? [15:09:03] <_jpl_> Sure. By default its name is the same as the class name. [15:09:34] <_jpl_> That's if you use the base Service class, but that's not even necessary. You can use junction.registerService yourself. [15:09:54] <_jpl_> An IService needs to support serviceName, that's all. [15:10:44] * Maniac is looking at the example [15:11:57] junction.callServiceMethod('myService', 'method', 'args') [15:13:47] <_jpl_> Except that anything after 'method' can be args, including keyword args. [15:13:52] <_jpl_> IIRC [15:14:13] <_jpl_> (yes, that's correct) [15:14:38] *args **kws? [15:15:17] * _jpl_ nods [15:16:13] just on a quick brushtrough it appears to be fairly tightly coupled to PB (apart from connectors.PB) is that correct? [15:17:24] <_jpl_> Ok, TODO.txt is checked in. [15:17:42] <_jpl_> Yes, it currently only works with PB. See TODO.txt. [15:18:01] <_jpl_> When peak.events comes along it won't look so Twisted. :) [15:18:38] (ah [15:19:33] high hopes for 1.0 :) [15:19:36] <_jpl_> The release after next (v0.7) should support other connection types. [15:20:11] as far as i understand it, to get up and running i can follow the simple examples right? [15:20:17] nothing else special to do [15:20:17] <_jpl_> Not really, those are basic messaging features. [15:20:39] <_jpl_> Yes, the example is fully functional. You could be able to run the config files and see it work. [15:22:05] <_jpl_> Oh wait, I need to update the example real quick like. [15:28:25] <_jpl_> It's a little broken at the moment for .ini-based configurations like this one... [15:29:53] i'm still struggling with the idea of how to extract results from a DM to send over a PB connection [15:30:46] <_jpl_> You probably want to turn the model object into a dict first, then rebuild it on the other side. That's what we do. [15:31:50] hmmm [15:32:17] basically extract everything and send the dict over [15:32:27] how do you mean rebuild ? [15:32:39] <_jpl_> That method isn't suitable for complex interconnected objects, though. You'll need PB-based DMs for that. [15:33:07] <_jpl_> I mean turn the dict into the object of the appropriate type at the other end of the connection. [15:34:04] like a PB client DM [15:35:29] <_jpl_> Right. [15:37:07] <_jpl_> You could probably even write a PB-DM superclass which does all the work, since model classes are pretty easy to introspect into. [15:37:23] <_jpl_> (via their .mdl_features property) [15:37:36] over my head now :) [15:39:26] <_jpl_> You're using classes based on peak.model.Element, right? [15:39:44] generally yes [15:39:58] or up till now with all sql based stuff, absolutely [15:41:25] <_jpl_> Element-based classes have a property called mdl_features, which is a list of the feature objects that model defines. Features are basically its properties, the ones that look like subclasses. [15:46:11] <_jpl_> So you can loop through that list of feature objects, read the name of the feature, and create a dict item with that name and value. On the receiving end you do the opposite. [15:48:57] <_jpl_> It could be as simple as this: [15:48:57] <_jpl_> d = {} [15:48:57] <_jpl_> for f in obj.mdl_features: [15:48:57] <_jpl_> d[f.attrName] = getattr(obj, attr, None) [15:50:02] <_jpl_> Though you might want to avoid creating values with None, just test first. [15:50:14] <_jpl_> (since None is a valid value) [15:50:44] <_jpl_> d = {} [15:50:44] <_jpl_> for f in obj.mdl_features: [15:50:44] <_jpl_> if hasattr(obj, attr): [15:50:44] <_jpl_> d[f.attrName] = getattr(obj, attr) [15:50:58] <_jpl_> oh wait [15:51:50] <_jpl_> d = {} [15:51:50] <_jpl_> for f in obj.mdl_features: [15:51:50] <_jpl_> if hasattr(obj, f.attrName): [15:51:50] <_jpl_> d[f.attrName] = getattr(obj, f.attrName) [15:52:21] <_jpl_> (was pasting a simplified version of some existing code and forgot about a variable definition) [15:54:14] so that would unpack on the other side? [15:54:35] er rebuild [15:55:29] <_jpl_> No, that would make the dict on the sending side. [15:56:47] <_jpl_> The reverse would be something like: [15:56:47] <_jpl_> obj = SomeModelClass() [15:56:47] <_jpl_> for f in obj.mdl_features: [15:56:47] <_jpl_> if f.attrName in d: [15:56:47] <_jpl_> setattr(obj, f.attrName, d[f.attrName]) [15:59:42] so the theory would be the PBClientDM would make the request and receive a dict and unpack it like above [16:00:31] <_jpl_> Yep. You'd need a service object on the other side which would do some sort of lookup and conversion to dictionary. You'd also need a way to make the PB call synchronous... [16:00:55] <_jpl_> I want planning on adding that to Junction, but peak.events should take care of that. [16:01:12] oh shoot. i didn't think of the synchronous issue [16:01:31] darn you twisted ! :( [16:02:41] <_jpl_> s/want/was [16:05:12] see my question on #twisted? :) [16:13:13] <_jpl_> Don't ask questions on #twisted unless you want to be called stupid. [16:13:25] yup [16:13:33] <_jpl_> It's pretty easy to do with a thread. I can show you how in a minute. [16:13:42] okie [16:14:12] <_jpl_> (remember, to Twisted fanatics, everything else is just stupid, categorically) [16:14:22] Yep. You'd need a service object on the other side which would do some sort of lookup and conversion to dictionary. [16:14:49] ok basically this just means a PB server which processes the call and converts to a dictionary and returns the result [16:15:43] in which case junction would work (so long as i was passing the correct types back and forth) [16:18:08] <_jpl_> (is there an echo in here?) [16:18:33] just attempting to quote [16:18:37] <_jpl_> Junction doesn't care about types... what do you mean? [16:19:23] i mean so long as i passed the dict back and forth [16:19:37] based on my model [16:21:03] <_jpl_> Sure, you might create a service Foo with a 'lookup' method, and call it like: junction.callServiceMethod('Foo', 'lookup', type='SomeClass', key=whatever) [16:22:09] <_jpl_> Foo.lookup might do an importString on 'type', lookup the DM for the class using storage.DMFor() (this is the DM on the server side, mind you), convert it to a dict, and return the result. [16:22:43] <_jpl_> You might then need some simple 'lookup' method on your server-side DMs to simplify things. [16:23:24] <_jpl_> Actually, if it's just going to be key-based, you wouldn't need that. [16:27:27] <_jpl_> Be back in a bit. [16:27:29] * _jpl_ idles [16:36:16] * Maniac waits for the thread async tip [17:35:38] * _jpl_ back [17:36:18] <_jpl_> I might build a little utility to do this. [17:40:36] <_jpl_> Build is a bit of an overstatement. It would just be one class with a couple of methods. [17:52:19] * _jpl_ idles again for a meeting [18:30:53] build would not be an understatement ! [18:31:03] i will heap praise upon you! [18:46:30] <_jpl_> hmm, it might be a little trickier than I first thought, since the reactor itself would need to be sent into its own thread, I think. [18:46:56] <_jpl_> Unless I have a separate thread run reactor.iterate() until the given deferred returns a value. [19:09:51] <_jpl_> yeah, that may be the way to go. You probably wouldn't want to use it more than once concurrently, tho. [19:46:26] <_jpl_> junction CVS is up to date, with fully functional examples again. [21:04:08] * Maniac goes to look [21:25:51] ** _jpl_ has left us