Bug 537401

Summary: DBUS communication hangs with PackageKit
Product: [openSUSE] openSUSE 11.2 Reporter: Stefan Schubert <schubi>
Component: WebYaSTAssignee: Martin Vidner <mvidner>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Blocker    
Priority: P2 - High CC: kkaempf
Version: FactoryFlags: coolo: SHIP_STOPPER-
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: ruby-dbus-debug.diff

Description Stefan Schubert 2009-09-08 13:26:48 UTC
First call of the service call http://0.0.0.0:3001/patches.xml returns the correct result. Addition requests hangs if the request will be repeated BEFORE PackageKit has been finished (due timeout).
The second call is successful if PackageKit has been finished before and will
be restarted again.
This is a reproduce able on different machines and a big problem cause the complete service hangs.
How to reproduce: Just call this request immediately after the response of the first call.
Martin, could you help here please cause that blocks me for installation many patches in a short timeframe ?
Comment 1 Klaus Kämpf 2009-09-08 15:22:30 UTC
From looking at the code, it seems as if a dbus daemon is started (main.loop). Shouldn't this be done in a separate Ruby thread ?
Comment 2 Martin Vidner 2009-09-08 15:28:39 UTC
> Shouldn't this be done in a separate Ruby thread ?
No: "Make it clear in the documentation that one should not call DBus from multiple threads"
https://trac.luon.net/ruby-dbus/ticket/22

Schubi, I don't know the PK API, but aren't you supposed to install all patches in a single transaction? That does not solve the bug, but would work around it.
Comment 3 Klaus Kämpf 2009-09-08 16:46:40 UTC
Its about retrieving a list of pending patches (i.e the /patches.xml REST path)
Comment 4 Klaus Kämpf 2009-09-08 16:47:20 UTC
I'm about to refactor the app/models/ code to make it testable and DRY.
Comment 5 Stefan Schubert 2009-09-09 06:49:50 UTC
I have checked my old code before refactoring and this works:

    obj_tid.on_signal("Package") do |line1,line2,line3|
          columns = line2.split ";"
          update = Patch.new(:resolvable_id => columns[1],
                             :kind => line1,
                             :name => columns[0],
                             :arch => columns[2],
                             :repo => columns[3],
                             :summary => line3 )
          patch_updates << update
      finished = true
    end

    obj_tid.on_signal("Error") do |u1,u2|
      finished = true
    end
    obj_tid.on_signal("Finished") do |u1,u2|
      finished = true
    end
    obj_tid_with_iface.GetUpdates("NONE")

    unless finished
      @main = MainPkg.new
      @main << system_bus
      @main.run
    end

Have a look to the finished flag. While the second call, the result is very fast (without using libzypp) and the process does not go into mainloop. That works. So the signal comes although the process has not gone into the mainloop.
I do not know who is caching here.
Comment 6 Martin Vidner 2009-09-09 07:42:08 UTC
I think I have the bug:
DBus::Connection has a message buffer, but DBus::Main does not check if it contains anything and goes to sleep on the socket right away.
Stay tuned for a fix.
Comment 7 Martin Vidner 2009-09-09 08:31:21 UTC
Fixed in http://github.com/mvidner/ruby-dbus/commit/2fca326bd857f528ff6ccb4bea7d8f9f8c98c7aa
Now it works for me. Please just copy over the changed file, I will make an RPM when I add a test.
Comment 8 Stefan Schubert 2009-09-09 09:23:46 UTC
Yes, it works. Thank you !!!
Comment 9 Martin Vidner 2009-09-09 13:56:47 UTC
Created attachment 317415 [details]
ruby-dbus-debug.diff

This is just a verbose debugging patch that does not fit in the library, so I keep it here.
Comment 10 Martin Vidner 2009-09-10 15:01:38 UTC
Fixed in YaST:Web ruby-dbus 0.2.10.