icaruseffect/syncthing-ubuntu-indicator

Gio interface runs out of free descriptors

Closed this issue · 6 comments

There is somewhere a problem with the usage of gio.
After some time it crashes because it's out of descriptors

closed with commit 0f3fa8e

It' still there i think. Maybe a problem with my system setup. I would be happy if anyone could confirm this. There should be an error in the debug.log then

Yes, this is still a problem. I've done a bunch of googling but can't find any solution to this using gio, so perhaps the only solution is to use something else. Help would be appreciated.

It caused me lots of headache (lots!)
The problem, so far that i understand it, is that gio creates descriptors/objects which are taking up memory/ reserve something/ stuff but this is quite undocumented. I read somewhere, that you have to destroy the created object to free the space again.
But then development stalled because i had exams.. and then i forgot to go on with the program.

the finally clause should do this. But somehow it doesn't happen.

I made this test script, which is just a bare-bones version of the syncthing indicator. This seems to work fine and runs for several hours without running out of descriptors. So this suggests that the problem is somewhere in the program. Maybe the file objects are being created faster than they are being destroyed.

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from gi.repository import Gtk, Gio, GLib
from gi.repository import AppIndicator3 as appindicator
import signal

class Main(object):
    def __init__(self):
        print 'Started main procedure'
        self.counter = 0
        GLib.idle_add(self.start_rest)

    def start_rest(self, param=None):
        self.counter += 1
        print 'start_rest', self.counter
        f = Gio.file_new_for_uri('http://127.0.0.1:8080/rest/connections')
        f.load_contents_async(None, self.fetch_rest, param)
#        del f

    def fetch_rest(self, fp, async_result, param):
        print 'fetch_rest', self.counter
        try:
            success, data, etag = fp.load_contents_finish(async_result)
            GLib.timeout_add_seconds(1, self.start_rest)
            if success:
                print data
            else:
                print 'fetch_rest: Scotty, we have a problem with REST: I cannot process the data'
        except:
            print 'could not connect to syncthing'
            GLib.timeout_add_seconds(4, self.start_rest)
#        finally:
#            del fp

if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    app = Main()
    Gtk.main()