Subject Re: [IB-Architect] Event datasets RFD
Author Bill Karwin
Jim,

You seem to be arguing against having a messaging capability in general.
I'd like to offer an explanation of why I think this feature is needed.

The current event mechanism allows a client to listen for a literal event by
name, but that requires that the server function that posts the event to
match that name. In the stock example, I can be notified that some stock
changed, but not which one or by how much. Once I receive the event
notification, it's time-consuming and inefficient to deduce the change that
spawned the event.

Customers have often requested some sort of event argument mechanism, even
if just a single value to indicate the key of the record that changed. An
alternative is for clients to specify event names with wildcards, so one
could listen on "Stock-*", a trigger could post "Stock-Redhat" and the
client would receive notification along with the full name of the posted
event.

I realized that wildcards and simple event arguments were in a way
equivalent. I also wasn't satisfied with that as a kludgey mechanism for
passing additional information. So I thought an XSQLVAR structure would be
more orthogonal with the client SQL interface.

The proper way to use messaging and avoid data that stales is to pass key
values, instead of attribute data. The client can then look up the
associated attribute data, based on the key. Therefore they have fresh
data, and also the ability to find it efficiently.

From: "Jim Starkey" <jas@...>
> The event API supports a 32K event block.
> Listening for 1,000 events is fully supported.
> The problem is not the design of the feature but the documentation.

The "real API" is not documented nor is it in ibase.h as far as I can tell.
Can you describe it?

> Bill, could you present a few scenarios on how your message
> interface would be used?

1. In the stock example, I would declare an interest in receiving
notification of 'Stock.MeteoricRise'.
2. I block on listening for the message.
3. In the trigger for stock prices, the server detects a sudden momentary
50% increase in the stock price for VA-Linux.
4. The trigger might post a traditional event NEW.COMPANY (like the old
example) as well as messages, 'Stock.Change', 'Stock.Rise', and
'Stock.MeteoricRise', each with the associated argument `SET COMPANY =
NEW.COMPANY'.
5. The transaction that changed the stock value commits.
6. My message-listener returns from blocking.
7. I retrieve the results (not the message data) to learn which messages
were posted.
8. The only one it tells me about is 'Stock.MeteoricRise' because I had
registered an interest in it. The other events and messages fall on deaf
ears and are discarded by the server.
9. I call isc_dsql_fetch() and retrieve an XSQLDA structure that contains a
CHAR(10) field COMPANY = 'VA-Linux'.
10. Now that I know it was VA-Linux that caused the commotion, I can start a
transaction, query the stocks table and look at the current state of this
stock price.

> So what is the
> value of giving them the price when it has to be assumed stale
> when they get it? Very, very little.

You shouldn't design a system to pass a message with the price or other
values that are likely to stale by the time they are received, any more than
you would design a system to cache query resultset data on the client and
rely on that for too long.

> 1. Event data will lead the lazy programmer into unwise
> program design, specifically assuming the event data
> is current or useful.

By this argument, InterBase shouldn't allow the programmer to control
transactions or to write arbitrary SQL. I'm not a fan of catering to the
laziest users.

> 2. A system that delivers event notifications is vastly
> cheaper in resource utilization than message delivery.

The mechanism I described delivers message notification in a manner very
similar to the event notification. The idea is that it sends message data
only on demand.

> A problem with your design is accounting for the lifetime of an
> even message. When does the server consider it delivered? When
> the server fetches the message from event manager? When the server
> sends the message delivering the message to the client? When the
> client receives the message? When it is queued on the client side?
> When the client program does a successful fetch?

Well, how is this handled with result sets based on conventional SQL
queries? I assume they are created and held as virtual datasets on the
server, and they expire under certain conditions. I am not familiar with
the criteria, but I assume it's something like when the client closes the
query or disconnects from the server.

We can extend that to expire a message dataset when _all_ interested clients
have disconnected, cancelled their interest in the message, or fetched the
dataset.

> What happens to
> messages in the virtual statement that are unread? Does the client
> send unread messages back to the server? Does it drop them on the
> floor?

The client doesn't receive the full message data until it requests it. We
can treat this similarly to any other query dataset. Does the server assume
the client has received and read the data once the server responds to a
fetch()?

> What if two parts of the program have declare independent
> interest in the events -- do both get the messages, or does one
> get all of the messages and the other none (the server can't
> tell that this is happening).

This is an interesting problem. I don't know the answer offhand.

> The existing mechanism to designed to handle all of these problems.
> It is simple, fast, cheap, and robust.

That's great for the event mechanism!

Messaging is likely to be less cheap and fast than simple events. One
cannot make the same assumptions to permit event collapsing and redundant
notification that allow the event mechanism to be so efficient. But I think
there is a legitimate need for messaging.

Bill Karwin