[Spread-users] Spread and reliable message communication

Tim Peters tim at zope.com
Fri Aug 8 18:38:56 EDT 2003


[Tuvi, Selim]
>> Actually the SP_receive call doesn't return any errors since we
>> don't get any exceptions from the Python wrapper. It just waits
>> as if no more mesages have been received.

OK, I'm over my Spread Head here.  SP_receive is never going to raise an
exception for you, because your receiver program never calls SP_receive
unless SP_poll first says the mbox has data to read:

while 1:
    while mbox.poll() == 0:
        time.sleep(0.001)
    msg = mbox.receive()

Now I've never used mbox.poll(), so am not familiar with its pragmatics.
This is the Python wrapper implementation of it:

static PyObject *
mailbox_poll(MailboxObject *self, PyObject *args)
{
	int bytes;
	PyObject *result = NULL;

	if (!PyArg_ParseTuple(args, ":poll"))
		return NULL;
	ACQUIRE_MBOX_LOCK(self);
	if (self->disconnected) {
		err_disconnected("poll");
		goto Done;
	}
	Py_BEGIN_ALLOW_THREADS
	bytes = SP_poll(self->mbox);
	Py_END_ALLOW_THREADS
	if (bytes < 0)
		result = spread_error(bytes, self);
	else
		result = PyInt_FromLong(bytes);
Done:
	RELEASE_MBOX_LOCK(self);
	return result;
}

It's clear, then, that SP_poll() is never returning a result less than 0 in
your app, and when Spread actually disconnects your receiver, SP_poll()
keeps returning 0, and you just sit in your polling loop forever.

If I comment out your polling code, leaving just

    msg = mbox.receive()

at the top of the loop, then I eventually see the expected disconnection
exception:

...
--> 294 239424 1429
Traceback (most recent call last):
  File "receiver.py", line 33, in ?
    msg = mbox.receive()
spread.error: (-8, 'Connection closed by spread')

So that's a question for the Spread folks:  is SP_poll(mbox) supposed to
return an error code if the mbox has been disconnected?  If it is, it
doesn't appear to be working.  (I'm using 3.16.2 here, btw.)

I note that the SP_poll() manpage only admits to one possible error return:

    Returns 0 if nothing is available or the number of bytes available,
    or one of the following errors ( < 0 ):

    ILLEGAL_SESSION
    The session specified by mbox is illegal. Usually because it is not
    active.

I don't think a disconnection counts as an illegal session.  Maybe it should
<wink>.


Something you can do instead:  a Spread mbox is really just a socket handle,
and can be passed to select() like any other socket handle.  With a
Python-level mbox, you get the socket handle to pass to select() via the
expression

    mbox.fileno()

Pass it in select's read list, and select will block until the socket is
ready to read.  This is saner than polling anyway.  You can also specify a
timeout to select if you don't want to wait forever.  I know this works
because it's what our app (the one we wrote the Python Spread wrapper to
support) does.  Unfortunately, I don't have our app's code available on the
machine I'm using right now, so can't show you the exact code to use.





More information about the Spread-users mailing list