Had to toss out my XMPP presence hack. Turns out that, at least in Google Talk, presence info is not sent to clients that have marked themselves unavailable, and that means the assistant would not see notifications, as it was nearly always marked unavailable as part of the hack.
I tried writing a test program that uses XMPP personal eventing, only to find that Google Talk rejected my messages. I'm not 100% sure my messages were right, but I was directly copying the example in the RFC, and prosody accepted them. I could not seem to get a list of extensions out of Google Talk either, so I don't know if it doesn't support personal eventing, or perhaps only supports certian specific types of events.
So, plan C... using XMPP presence extended content. The assistant generates a presence message tagged "xa" (Extended Away), which hopefully will make it not seem present to clients. And to that presence message, I add my own XML element:
<git-annex xmlns='git-annex' push="uuid,uuid" />
This is all entirely legal, and not at all a hack. (Aside from this not really being presence info.) Isn't XML fun?
And plan C works, with Google Talk, and prosody. I've successfully gotten push notifications flowing over XMPP!
Spent some hours dealing with an unusual probolem: git-annex started segfaulting intermittently on startup with the new XMPP code.
Haskell code is not supposed to segfault..
I think this was probably due to not using a bound thread for XMPP, so if haskell's runtime system recheduled its green thread onto a different OS thread during startup, when it's setting up TLS, it'd make gnuTLS very unhappy.
So, fixed it to use a bound thread. Will wait and see if the crash is gone.
Re-enabled DBUS support, using a new version of the library that avoids the memory leak. Will need further changes to the library to support reconnecting to dbus.
Next will be a webapp configuration UI for XMPP. Various parts of the webapp will direct the user to set up XMPP, when appropriate, especially when the user sets up a cloud remote.
To make XMPP sufficiently easy to configure, I need to check SRV records to
find the XMPP server, which is an unexpected PITA because getaddrinfo
can't do that. There are several haskell DNS libraries that I could use for
SRV, or I could use the host
command:
host -t SRV _xmpp-client._tcp.gmail.com
Sure, I could, as I'm operating my own server anyway. Others might not be willing to go to some random server and create another account, though.
Reviewing RFC 6121: Did you try negative priorities for your resources already? It's possible that Gtalk does something weird but in theory they should be ignored for messages directed to non-qualified JIDs (i.e. without an explicit resource setting). Setting "xa" alone won't help you anything, it will only cause the others to see you as "xa" but that's a perfectly valid common chat status where you expect messages to be queued in the client until the user returns.
I hadn't tried it, but it looks like a very good idea. I will have to change my protocol a little bit as I currently sometimes send chat messages not directed to a specific client, in order to reach any clients using an account. To reach clients with a negative priority, chat messages have to be directed at the client.
Ok, done; priority is set to -1 and all the XMPP messaging in git-annex still seems to work!
I don't know though, that this entirely solves the problem. In particular, a regular xmpp client may decide to direct a chat message at a git-annex client, due to that being the only client connected. If this does become a problem, I suppose git-annex could buffer and re-send such messages when it sees a regular client connect. Or it could show them in the webapp, but that seems feature creep.