Package org.jcsp.lang

# Class Any2OneCallChannel

java.lang.Object
org.jcsp.lang.Guard
org.jcsp.lang.AltingChannelAccept
org.jcsp.lang.Any2OneCallChannel

All Implemented Interfaces:
  `Serializable`, `ChannelAccept`

public abstract class Any2OneCallChannel extends AltingChannelAccept implements Serializable
This is the super-class for any-to-one `interface`-specific CALL channels, safe for use by many clients and one server.

Shortcut to the Constructor and Method Summaries.

## Description

Please see `One2OneCallChannel` for general information about CALL channels. Documented here is information specific to this any-1 version.

### Converting a Method Interface into a Variant CALL Channel

Constructing a any-1 CALL channel for a specific `interface` follows exactly the same pattern as in the 1-1 case. Of course, it must extend `Any2OneCallChannel` rather than `One2OneCallChannel`.

For example, using the same `Foo` interface as before, we derive:

     import org.jcsp.lang.*;

     public class Any2OneFooChannel extends Any2OneCallChannel implements Foo {

       ...  same body as One2OneFooChannel

     }

### Calling a CALL Channel

All the client needs to see is the method `interface` implemented by the CALL channel. So far as the client is concerned, therefore, there is no difference between any of the varieties of CALL channel - it just makes the call.

### Accepting a CALL Channel

The mechanics of accepting a CALL channel are the same for all varieties. However, the server should declare which kind (or kinds) it allows to be attached:

     import org.jcsp.lang.*;

     class B implements CSProcess, Foo {

       private final ChannelAccept in;

       public B (final One2OneFooChannel in) {         // original constructor
         this.in = in;
       }

       public B (final Any2OneFooChannel in) {        // additional constructor
         this.in = in;
       }

       ...  rest as before

     }

When wrapping the above to hide its raw method interface, don't forget to include the extra constructor(s):

     import org.jcsp.lang.*;

     public class B2 implements CSProcess {            // no Foo interface

       private final B b;

       public B2 (final One2OneFooChannel in) {        // original constructor
         b = new B (in);
       }

       public B2 (final Any2OneFooChannel in) {       // additional constructor
         b = new B (in);
       }

       public void run () {
         b.run ();
       }

     }

### ALTing on a CALL Channel

The server may ALT on a any-1 CALL channel, just as it may ALT on a 1-1 one. As before, it needs to make its intentions explicit. So, in the above example, the first field declaration of `B` needs to become:

       private final AltingChannelAccept in;

See below for an example of `ALT`ing between CALL channels.

### Building a CALL Channel Network

Network building with CALL channels is the same as building with ordinary channels. First construct the channels and, then, construct the processes - plugging in the channels as required and running them in `Parallel`.

For example, the network consisting of one server and several clients:

where `A` is unchanged from its definition in `One2OneCallChannel`, is implemented by:

         Any2OneFooChannel c = new Any2OneFooChannel ();

         final A[] aClients = new A[n_aClients];
         for (int i = 0; i invalid input: '<' aClients.length; i++) {
           aClients[i] = new A (c);
         }

         new Parallel (
           new CSProcess[] {
             new Parallel (aClients),
             new B2 (c)
           }
         ).run ();

## Example

This is a CALL channel version of the Wot-no-Chickens example:

The `service` CALL channel replaces the `request`/`deliver` channel pair of the earlier example. Previously, the philosopher had to perform two actions to get a chicken - a `request.write` followed by a `deliver.read`. Now, its interaction with the canteen is a single CALL on `service.takeChicken`.

The `supply` CALL channel replaces the ordinary channel of the same name. Previously, the chef still had to perform two actions to supply the chickens - a `supply.write` followed by a second `supply.write`. This was to model the extended period while the chef set down the chickens in the canteen. The first communication synchronised the chef with the canteen, getting its exclusive attention. The canteen then executed the set-down delay before accepting the second communication and, hence, releasing the chef. Now, this interaction is a single CALL on `supply.freshChickens`.

The other difference with the earlier example is that the college now employs many chefs. This has two minor impacts. It needs to be able to support any-1 CALLs on its `supply` channel (as well as on `service`). Secondly, with all those chefs, it needs to be able to refuse further supplies of chicken if it has run of room.

### The Canteen

There are two other differences in design between the canteen server here and the CALL channel servers documented above and in `One2OneCallChannel`. The first is trivial - we have inlined the real server as an anonymous inner class of the public `Canteen` wrapper. The second is more subtle, but also trivial. Often, a CALL channel is constructed for a specific server interface and there is no intention for it to be used for communicating with any other server. In which case, it makes sense to tie that interface, together with its corresponding CALL channel, into the server as inner declarations.

So, the Canteen first publishes its two specific interfaces and matching CALL channels. The CALL channels follow the defined pattern, omitting the optional setting of `selected` (since each interface contains only one method):

     import org.jcsp.lang.*;

     class Canteen implements CSProcess {

       public static interface Service {
         public int takeChicken (String philId);
       }

       public static class One2OneServiceChannel
        extends One2OneCallChannel implements Service {
         public int takeChicken (String philId) {
           join ();
           int n = ((Service) server).takeChicken (philId);
           fork ();
           return n;
         }
       }

       public static class Any2OneServiceChannel
        extends Any2OneCallChannel implements Service {
         public int takeChicken (String philId) {
           join ();
           int n = ((Service) server).takeChicken (philId);
           fork ();
           return n;
         }
       }

       public static interface Supply {
         public int freshChickens (String chefId, int value);
       }

       public static class Any2OneSupplyChannel
        extends Any2OneCallChannel implements Supply {
         public int freshChickens (String chefId, int value) {
           join ();
           int n = ((Supply) server).freshChickens (chefId, value);
           fork ();
           return n;
         }
       }

Note that we have defined both 1-1 and any-1 versions of the `Service` CALL channel. This example makes use only of the any-1 variant - the other will be used in a later exercise.

Next we set up the constructor and the local fields for saving its parameters:

       private final AltingChannelAccept service;   // shared from all Philosphers
       private final AltingChannelAccept supply;    // shared from all Chefs
       private final int serviceTime;
       // how long a philosopher spends in the canteen
       private final int supplyTime;
       // how long a chef spends in the canteen
       private final int maxChickens;
       // maximum number of chickens in the canteen

       public Canteen (Any2OneServiceChannel service, Any2OneSupplyChannel supply,
                       int serviceTime, int supplyTime, int maxChickens) {
         this.service = service;
         this.supply = supply;
         this.serviceTime = serviceTime;
         this.supplyTime = supplyTime;
         this.maxChickens = maxChickens;
       }

Now, we need to combine the exported interfaces into a single one so that the inner process can be created (anonymously) by this wrapper's run method:

       private interface inner extends CSProcess, Service, Supply {};

       public void run () {

         new inner () {

           private int nChickens = 0;
           private int nSupplied = 0;

           private final CSTimer tim = new CSTimer ();

Impementations of the required CALL interfaces come next:

           public int takeChicken (String philId) {
           // pre : nChickens > 0
             System.out.println ("   Canteen -> " + philId
                                 + " : one chicken ordered ... "
                                 + nChickens + " left ... ");
             tim.sleep (serviceTime);
             nChickens--;
             nSupplied++;
             System.out.println ("   Canteen -> " + philId
                                 + " : one chicken coming down ... "
                                 + nChickens + " left ... ["
                                 + nSupplied + " supplied]");
             return 1;
           }

           public int freshChickens (String chefId, int value) {
           // pre : nChickens invalid input: '<' maxChickens
             System.out.println ("   Canteen invalid input: '<'- " + chefId
                                 + " : ouch ... make room ... ");
             tim.sleep (supplyTime);
             nChickens += value;
             int sendBack = nChickens - maxChickens;
             if (sendBack > 0) {
               nChickens = maxChickens;
               System.out.println ("   Canteen invalid input: '<'- " + chefId
                                   + " : full up ... sending back "
                                   + sendBack);
             } else {
               sendBack = 0;
             }
             System.out.println ("   Canteen invalid input: '<'- " + chefId
                                 + " : more chickens ... "
                                 + nChickens + " now available ... ");
             return sendBack;
           }

and the run method that conducts everything:

           public void run () {

             final Alternative alt = new Alternative (new Guard[] {supply, service});
             final boolean[] precondition = {true, false};
             final int SUPPLY = 0;
             final int SERVICE = 1;

             System.out.println ("   Canteen : starting ... ");
             while (true) {
               precondition[SERVICE] = (nChickens > 0);
               precondition[SUPPLY] = (nChickens invalid input: '<' maxChickens);
               switch (alt.fairSelect (precondition)) {
                 case SUPPLY:
                   supply.accept (this);      // new batch of chickens from a chef
                 break;
                 case SERVICE:
                   service.accept (this);     // a philosopher wants a chicken
                 break;
               }
             }

           }

Finally, don't forget to run this inner process:

         }.run ();

       }

     }

### The Philosopher

As in the original example, philosophers spend their time thinking, feeling hungry, calling on the canteen and, once served, eating. Except, of course, for greedy philosophers who never stop to think:

     import org.jcsp.lang.*;

     class Phil implements CSProcess {

       private final String id;
       private final Canteen.Service service;
       private final int thinkTime;
       private final int eatTime;
       private final boolean greedy;

       public Phil (String id, Canteen.Service service,
                    int thinkTime, int eatTime, boolean greedy) {
         this.id = id;
         this.service = service;
         this.thinkTime = thinkTime;
         this.eatTime = eatTime;
         this.greedy = greedy;
       }

       public void run () {
         final CSTimer tim = new CSTimer ();
         int nEaten = 0;
         while (true) {
           if (! greedy) {
             System.out.println ("   Phil " + id
                                 + " : thinking ... ");
             tim.sleep (thinkTime);  // thinking
           }
           System.out.println ("   Phil " + id
                               + " : gotta eat ... ");
           int chicken = service.takeChicken (id);
           nEaten++;
           System.out.println ("   Phil " + id
                               + " : mmm ... that's good ["
                               + nEaten + " so far]");
           tim.sleep (eatTime);      // eating
         }
       }

     }

### The Chef

Chefs cook chickens in batches of `batchSize`, taking `batchTime` milliseconds per batch. When a batch is ready, the chef supplies it to the canteen. The chef has to wait until the canteen is prepared to take it and, then, helps to set down the batch (before returning with any for which there was no space) - all this happens during the CALL of `supply.freshChickens`:

     import org.jcsp.lang.*;

     class Chef implements CSProcess {

       private final String id;
       private final int batchSize;
       private final int batchTime;
       private final Canteen.Supply supply;

       public Chef (String id, int batchSize, int batchTime, Canteen.Supply supply) {
         this.id = id;
         this.batchSize = batchSize;
         this.batchTime = batchTime;
         this.supply = supply;
       }

       public void run () {

         final CSTimer tim = new CSTimer ();

         int nReturned = 0;
         int nSupplied = 0;

         while (true) {
           System.out.println ("   Chef " + id + " : cooking ... "
                               + (batchSize - nReturned) + " chickens");
           tim.sleep (batchTime);
           System.out.println ("   Chef " + id + " : "
                               + batchSize + " chickens, ready-to-go ... ");
           nReturned = supply.freshChickens (id, batchSize);
           nSupplied += (batchSize - nReturned);
           System.out.println ("   Chef " + id + " : "
                               + nReturned + " returned ["
                               + nSupplied + " supplied]");
         }
       }

     }

### The Clock

The college is feeling generous and provides a clock. This just ticks away, delivering time-stamps roughly every second (and maintaining real-time). It is independent of the rest of the system.

     import org.jcsp.lang.*;

     class Clock implements CSProcess {

       public void run () {

         final CSTimer tim = new CSTimer ();
         final long startTime = tim.read ();

         while (true) {
           int tick = (int) (((tim.read () - startTime) + 500)/1000);
           System.out.println ("[TICK] " + tick);
           tim.sleep (1000);
         }

       }

     }

### The College

Despite the greedy behaviour of philosopher 0 (Bill), nobody starves in this college. Three chefs are provided with differing cooking speeds and batch sizes. Pierre is the original lightning chef, cooking 4 chickens in 2 seconds flat. Henri is more leisurely, taking 20 seconds to cook his batch of 10. Sid has been sent down by the new owners of the college, who are into mass catering. He produces 100 chickens every 150 seconds, which is a bit silly since the canteen has only space for 50. Still, it enables Bill to get really sick!

For convenience, the college network diagram is reproduced here - this time including the clock and naming some of the characters:

Here is the code:

     import org.jcsp.lang.*;

     class College implements CSProcess {

       public void run () {

         final String[] philId = {"Bill", "Hilary", "Gennifer", "Paula", "Monica"};

         final int thinkTime = 3000;             // 3 seconds
         final int eatTime = 100;                // 100 milliseconds

         final int serviceTime = 0;              // 0 seconds
         final int supplyTime = 3000;            // 3 seconds
         final int maxChickens = 50;

         final Canteen.Any2OneServiceChannel service
           = new Canteen.Any2OneServiceChannel ();
         final Canteen.Any2OneSupplyChannel supply
           = new Canteen.Any2OneSupplyChannel ();

         final Phil[] phils = new Phil[philId.length];
         for (int i = 0; i invalid input: '<' phils.length; i++) {
           phils[i] = new Phil (philId[i], service, thinkTime, eatTime, i == 0);
         }

         new Parallel (
           new CSProcess[] {
             new Clock (),
             new Canteen (service, supply, serviceTime, supplyTime, maxChickens),
             new Parallel (phils),
             new Chef ("Pierre", 4, 2000, supply),
             // chefId, batchSize, batchTime
             new Chef ("Henri", 10, 20000, supply),
             new Chef ("Sid", 100, 150000, supply)
           }
         ).run ();

       }

       public static void main (String argv[]) {
         new College ().run ();
       }

     }

### A Note about `System.out` and Other Non-Blocking Monitors

The college network diagram and code hides a key player that quietly coordinates the reporting of all activity - `System.out`. All the processes share this object as a common resource, making heavy and concurrent demands on its `println` service. Why is this safe?

Consider a Java object whose public methods are all `synchronized` but contain no invocations of `wait` or `notify` (a passive non-blocking monitor). Such an object is equivalent to a `CSProcess` serving one or more any-1 CALL channels (whose interfaces reflect those `synchronized` methods) and whose `run` consists of an endless loop that does nothing except unconditionally `accept` any CALL.

So, a simple non-blocking monitor is always safe to share between concurrent JCSP processes and, currently, carries less overheads than its active server equivalent. See `DisplayList` for an example from the JCSP library. Another example is ``java.io.PrintStream``, of which `System.out` is an instance. Its `print`/`println` methods are `synchronized` on itself (although this does not seem to be documented and you have to look hard at the code to find out). So, to show the full story, the above diagram possibly needs an overlay that adds a System.out process servicing a any-1 println CALL channel, with all the other processes as clients. This is left as an exercise.

Of course, it would be nice if such monitors were accessed via an `interface`, so that client processes had neither direct visibilty of them nor concern about their behaviour. A problem with the above college is that `System.out` - and the concept of printing a line of text - is burnt into the code of all its processes. If we wanted to change the output of the college from a scrolling text display into some graphics animation, all those processes would have to be changed.

A better design would pass in channel (or CALL channel or non-blocking monitor) interfaces to each of the college processes. These would merely report their identities and states by writing to (or calling or invoking) those interfaces. To reproduce the current display, all those interfaces would be instanced by a single any-1 channel (or CALL channel or monitor) connected to a simple server that responds by making `System.out.println` invocations appropriate to the information passed. For other effects, connect in other servers. Note that the college processes do not have to be connected to the same server - each could be connected to a separate server and these servers connected into a graphics animation network (incorporating, for example, processes from `org.jcsp.awt`). The point is that the college processes would need no changing to drive whatever was constructed. This is also left as an exercise.

### Further Thoughts on the Canteen Design

The decision to bind in the CALL channel (and associated inteface) definitions as inner classes of `Canteen` does not fit comfortably with the above observations. However, processes servicing `Canteen.Any2OneServiceChannel` or `Canteen.Any2OneSupplyChannel` channels do not have to be instances of `Canteen` - even though that would seem to be a little odd. So, the `College` authorities still have freedom to install canteens with behaviours quite different to that of `Canteen`. [Anything with the same channel interface will fit! The interoperability of processes depends only on the compatibility of their channel interfaces. Note that this reusability owes nothing to the concept of inheritance - for example, the alternative canteens pluggable into the college network need no special sub-classing relationships.] So, if we really want to allow this flexibility, make it explicit by declaring the CALL channels separately from any of their servers.

Another design choice is to burn in CALL channel instances as part of the servers themselves. For example, the `Canteen` class could construct and export its `service` and `supply` channels as `public` and `final` fields (rather than import them via constructor parameters). In this case, the `College` builder would need to declare and name the canteen (instead of declaring and naming the channels):

     import org.jcsp.lang.*;

     class College implements CSProcess {

       public void run () {

         ...  declare constants (nPhilosophers, thinkTime etc.)

         final Canteen canteen = new Canteen (serviceTime, supplyTime,
                                              maxChickens);

         final Phil[] phils = new Phil[nPhilosophers];
         for (int i = 0; i invalid input: '<' phils.length; i++) {
           String philId = new Integer (i).toString ();
           phils[i] = new Phil (philId, canteen.service,
                                thinkTime, eatTime, i == 0);
         }

         new Parallel (
           new CSProcess[] {
             new Clock (),
             canteen,
             new Parallel (phils),
             new Chef ("Pierre", 4, 2000, canteen.supply),
             new Chef ("Henri", 10, 20000, canteen.supply),
             new Chef ("Sid", 100, 60000, canteen.supply)
           }
         ).run ();
       }
       ...  main
     }

Note that this particular burn in does not deny any flexibility to the college in choosing any particular variety of canteen. In fact, the only thing of interest to the college is that the canteen provides and services CALL channels whose interfaces are what its philosophers and chefs expect (i.e. `Service` and `Supply`). Note also that the college network diagram has not changed.

Having gone this far, we may like to consider making the server self-starting - so that its declaration not only introduces its service channels but also brings it to life. For example, this could be done for the `Canteen` by adding the following as the last line of its constructor:

         new ProcessManager (this).start ();

Of course, the `canteen` instance should then be removed from the `Parallel` construction above.

[Warning: be careful if sub-classes are allowed (i.e. the `Canteen` class was not declared `final`). In this case, the above incantation should be optional so that each sub-class constructor can invoke a super-class constructor that omits it. If we let the super-class fire up the process, it may start running before the sub-class constructor finishes - i.e. before the process has been fully initialised. It must be the sub-class constructor that self-starts the process (as the last thing it does).]

[Note: a self-starting server exporting its own CALL (or ordinary) channels for public concurrent use corresponds to the occam3 notion of a `MODULE` implemented by a `RESOURCE`.]

Author:
  P.H. Welch
See Also:
  - `One2OneCallChannel`
  - `One2AnyCallChannel`
  - `Any2AnyCallChannel`
  - `Alternative`
  - Serialized Form

## Field Summary

Fields
Modifier and Type
Field
Description
`protected int`
`selected`
This may be set during the standard calling sequence to record which method was invoked by a client.
`protected CSProcess`
`server`
This holds a reference to a server process so that a client may make the call.

## Constructor Summary

Constructors
Constructor
Description
`Any2OneCallChannel()`

## Method Summary

Modifier and Type
Method
Description
`int`
`accept(CSProcess server)`
This is invoked by a server when it commits to accepting a CALL from a client.
`protected void`
`fork()`
This is invoked by a client during the standard calling sequence.
`protected void`
`join()`
This is invoked by a client during the standard calling sequence.

### Methods inherited from class org.jcsp.lang.Guard

`schedule`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### server

protected CSProcess server
This holds a reference to a server process so that a client may make the call. The reference is only valid between the ``join`` and ``fork`` elements of the standard calling sequence. As shown in that sequence, it will need casting up to the relevant interface supported by the specific CALL channel derived from this class.

### selected

protected int selected
This may be set during the standard calling sequence to record which method was invoked by a client. It is only safe to do this between the ``join`` and ``fork`` elements of that sequence. Either all the CALL channel methods should do this or none - in the latter case, its default value remains as zero. Its value is returned to a server as the result the server's invocation of ``accept``.

## Constructor Details

### Any2OneCallChannel

public Any2OneCallChannel()

## Method Details

### accept

public int accept(CSProcess server)
This is invoked by a server when it commits to accepting a CALL from a client. The parameter supplied must be a reference to this server - see the example from `One2OneCallChannel`. It will not complete until a CALL has been made. If the derived CALL channel has set the `selected` field in the way defined by the standard calling sequence, the value returned by this method will indicate which method was called.

Specified by:
  `accept` in interface `ChannelAccept`
Parameters:
  `server` - the server process receiving the CALL.

### join

protected void join()
This is invoked by a client during the standard calling sequence. It will not complete until a server invokes an ``accept`` on this channel. In turn, that `accept` will not complete until the client invokes a ``fork``, after having made its CALL on the server.

### fork

protected void fork()
This is invoked by a client during the standard calling sequence. A server must have invoked an ``accept`` for the client to have got this far in the sequence - see the ``join``. This call unblocks that `accept`, releasing the server and client to resume separate lives.