[packagekit] spawned backends, and dispatcher
Richard Hughes
hughsient at gmail.com
Sun Sep 7 02:20:39 PDT 2008
Tim Lauridsen and I got hacking one Friday night, the conversation went
kind of like this (summarised):
timlau: I've committed a change to the yum backend to use a dispatcher
hughsie: what's that?
timlau: Allows you to submit extra stdin to an existing python process
hughsie: cool, I'll do the C bits
Anyway, after a couple of hours of hacking we've converted the yum
backend to use a dispatcher. This means we don't have to keep reloading
it every time we click on something in the GUI, and everything is a lot
quicker. There's quite a bit of complexity about handling different
locales and proxy settings from different concurrent sessions, but it
all's unit tested and now seems to work pretty well.
I'll paste what I added to the docs:
There are two modes of operation for a spawned backend, a one shot mode
and a dispatcher mode.
* The "one-shot" mode is where commands are executed (e.g.
search-name.py none power), which then initialises the package
backend, returns results and then exits. This is obviously not
ideal, as some backends like smart can take several hundred ms
to initialise, and this leads to a "laggy" GUI applications.
This however is the easiest mode to implement, and the original
one supported by all versions of PackageKit.
* The "dispatcher" mode is where a command is used to startup the
backend, for instance yumBackend.py search-name none power and
then the backend then sits and waits for more standard input.
Further operations can be done on the loaded backend sending
commands to stdin, e.g. search-name none power. If there are no
more operations after a preset time (default 5 seconds) then the
backend is sent exit over stdin, and the backend terminates. The
daemon will ensure the operations are serialised, and that
backends not sending finished are cleaned up properly.
This is quite easy to implement (see the end of yumBackend.py),
and is supported from PackageKit version 0.3.2. The dispatcher
mode does not have to implemented in python; any language that
can read from stdin can block and be used in this way.
Now, the dispatcher mode is only lightly tested, but seems to pass all
the self checks in the code with flying colours.
If you want to convert your code (looking at you, afb and kenvandine)
then it's really simple. Just change your calls in your
pk-backend-xxxx.c from:
- pk_backend_spawn_helper (spawn, "fooBackend.py", "get-packages.py", filters_text, NULL);
+ pk_backend_spawn_helper (spawn, "fooBackend.py", "get-packages", filters_text, NULL);
And then add something like this in fooBackend.py (and remove the tiny
*.py helper scripts):
def main():
backend = PackageKitFooBackend('',lock=True)
args = sys.argv[1:]
backend.dispatch_command(args[0],args[1:])
while True:
line = raw_input('')
if line == 'exit':
break
args = line.split(' ')
backend.dispatch_command(args[0],args[1:])
if __name__ == "__main__":
main()
I'm going to test the yum backend some more today with the dispatcher
mode turned on, and hopefully release 0.3.2 with that change on by
default.
Note, this isn't designed to stick around for a long time like the dbus
backends (maximum of 5 seconds), and so don't think for a minute the
dbus backends are deprecated. I will remove the yum2 backend, as it's
obvious that the yum backend is kept more up to date and is much more
stable.
Richard.
More information about the PackageKit
mailing list