[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Channels versus Methods
Thomas,
Your approach is very nice and I have thought about something similar, but I
found it restrictive in several ways. My comments are below.
Gerald.
-----Original Message-----
From: Thomas Umland [mailto:Thomas.Umland@xxxxxxxxxxx]
Sent: donderdag 1 juli 1999 0:25
To: java-threads@xxxxxxxxx
Cc: occam-com@xxxxxxxxx; Thomas Umland
Subject: Re: Channels versus Methods
Hi Peter and Gerald,
your ideas are quite good. In fact my first ideas were similar to yours.
But the major drawback of this approach is, that you need either on the
client or on the server side a pair of corresponding read/write
statements. The compiler unfortunately cannot check their presence. If
the programmer forgets one of these, the system will hang
Hmm, this is always a drawback. Each channel input output pair must match in
the application. If the programmer forgets to put a read() or write() method
somewhere in the program then this program may hang. Isn't this why we want
to use CSP channels? Forgetting reads or writes results in wrong events, but
those are easier to trace than tracing bugs with monitors. The programmer of
the server application also creates the CALL Channels and must know how to
communicate with the CALL Channel at the client side. Is this really a
drawback or just a matter of taste? However, I like your idea to make things
safer.
My approach is different. On the client side I use a "write" command
similar to the one we already have in ordinary channels, except that it
returns an object; that is straight forward and trivial:
public Object write (Object object);
The nice thing about CALL channels is that you can use other names than just
'write', such as calculate(..,..,..), closeValve() or processQuery(..),
which makes the code better readable.
The trick is on the server side where the "read" method gets a new
interface as parameter:
public Object read (CallChannelFunctionInterface function);
Has the channel two read methods?
1. Object read()
2. Object read(CallChannelFunctionInterface function)
(snip)
The Canteen looks like this:
AltingChannelInput request;
PileOfChickens pileOfChickens = new PileOfChickens ();
...
switch (alt.fairSelect (preCondition)) {
case REQUEST:
Integer wanted = (Integer) request.read (pileOfChickens);
// "read" reads the input and sends the return value!
// or if you don't need the trasmitted number simply say:
// request.read (pileOfChickens);
break;
case SUPPLY:
...
The "PileOfChickens" is luxury version of
"CallChannelFunctionInterface":
class PileOfChickens implements CallChannelFunctionInterface {
private int nChickens;
// constructor
PileOfChickens () { this.nChickens = 0; }
// the return function of out CALL channel:
public Object accept (Object input) {
int wanted = ((Integer) input).intValue();
int ok = min (wanted, nChickens); // may be, not enough chickens
there
nChickens -= ok;
return new Integer (ok);
}
// get the actual size
int size () { return nChickens; }
// add some chickens
void add (int incr) { nChickens += incr;}
int min (int a, int b) { if (a < b) return a; else return b;}
}
What do you think of this? Have I overseen something?
For each CALL channel you need to create a class with an accept() method.
The tasks of the accept() methods are invisible for the server. However,
decisions that are taken by these methods may depend on the state of the
server or on the states of other accept() methods. They do not share the
state of the server and sharing states makes it complex. This is why reading
and writing by the server is practical.
What must be done if one wants an Object accept(Object in1, Object in2, ...)
method instead of accept(Object in).?
Does this also work for ChannelInt and all others?
You are using dynamic binding (or casting) in the accept() method. This will
not only be checked by the compiler, but also checked at run-time. A wrong a
rgument and things goes wrong. Is this a drawback?
Thomas