﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
42	notifyOnDisconnect() could use weakrefs	Brian Warner		"I've been struggling with the usability aspects of notifyOnDisconnect(),
which lets you attach a callback to a !RemoteReference that will tell you
when the other end goes away (i.e. a network partition occurs, because of a
TCP connection being severed). This returns a ""marker"" object (really a
tuple, but it should be replaced by an anonymous instance), which can be
passed to the corresponding dontNotifyOnDisconnect() to remove the callback.

The problem is that managing the callback is a serious hassle. I've seen two
main use cases for notifyOnDisconnect. The first is a publish/subscribe
pattern, where you keep a set of !RemoteReferences (that you plan to iterate
over and send messages to each later on), and you want to reduce memory
consumption by removing them from the set as soon as they cease being useful.
(if you didn't care about the memory usage, you could always just leave them
there, and catch the !DeadReferenceError that will occur when you use a stale
one)

The second is when the !RemoteReference is used as a ""canary"", basically when
the remote side has access to one of your own objects, and you want to find
out when they lose contact with it. The Tahoe example is that clients who
want to upload data contact the storage server and get access to a writer
facet, to which they send a bunch of data before calling close(). If the
client drops off the network before calling close(), the server is supposed
to delete the partial share. To enable this, a client-side ""canary"" object is
passed to the server, and the server uses notifyOnDisconnect to discover when
the client has gone away.

E has a ""{{{__reactToLostClient}}}"" method, and notifyOnDisconnect is implemented
on top of it. In Foolscap we currently do it the other way around, where an
application-visible canary is used, implemented on top of notifyOnDisconnect.


Anyways, the problem is that once notifyOnDisconnect is called, there will
come a time when we no longer care to hear about the disconnection, and there
are usually two code paths that bring this era of caring to an end: when the
subscriber has removed themselves, or when the upload-like action has
finished. To make sure we don't double-call dontNotifyOnDisconnect, we must
keep careful track of our state, and it's easy to get it wrong.

Writing this up makes me realize that the subscription case might be handled
better by not bothering with notifyOnDisconnect, and instead just leaving the
!RemoteReferences in the collection until they fail of their own accord (by
catching !DeadReferenceError). But I think the canary case is still tricky.

The idea that prompted me to write this ticket was that we might use weakrefs
to make it easier to manage these callbacks. The idea would be that once
everyone else has forgotten about the !RemoteReference, then the Tub should
too. The immediate problem that I can imagine is the uncertainty: if you've
forgotten about the RR, but it hasn't been gc'ed yet, then your callback
could still be fired.

hmmm.

"	enhancement	new	major	undecided	usability	0.2.2		disconnect	
