• No results found

Session-Based Web Service Programming for Business Protocols

N/A
N/A
Protected

Academic year: 2021

Share "Session-Based Web Service Programming for Business Protocols"

Copied!
86
0
0

Loading.... (view fulltext now)

Full text

(1)

Session-Based Web Service

Programming for Business

Protocols

Project Final Report

Michael Emmanuel

(2)

Abstract

Session-based programming uses a type discipline to guarantee the correctness of interactions taking place between communicating processes. Session-Java is a language under development, integrating object-orientated programming and session types. In this project we will attempt to use the language to imple-ment several Business Protocols dealing with Web Services. Our goal is to test the language and identify its properties relative to other approaches such as RMI, socket programming and COBRA. We want to rate it’s suitability in pro-gramming business interactions and it’s applicability to the increasingly popular domain of Web Services. The end product of our efforts will be our documented implementations of the business protocols including the implementation of a complicated scenario taken from the paper “Web Services Choreography Re-quirements”[2].

(3)

Acknowledgements

I would like to thank a few people for their contributions to this project: • Nobuko Yoshida for her precious guidance and support throughout the

project

• Raymond Hu for introducing me to SJ, putting up with me and for his continuous support and encouragement

(4)

Contents

1 Overview 1 1.1 Introduction . . . 1 1.2 Contributions . . . 2 1.3 Structure of Report . . . 3 2 Background 4 2.1 Session Programming . . . 4

2.2 Merging Object Orientated with Session-Typed programming . . 6

2.3 Session-Java (SJ) . . . 7

2.3.1 Main Properties . . . 7

2.3.2 Using SJ . . . 7

3 The two SJ versions used in this project 14 3.1 Overview . . . 14

3.2 Quickstart Scenario . . . 14

3.3 The differences in the two versions . . . 15

4 The TicketAgency Scenario 19 4.1 Variation 1 . . . 19 4.1.1 Description . . . 19 4.1.3 Protocols . . . 20 4.1.2 Interactions . . . 21 4.1.4 Implementation . . . 21 4.1.5 Comments . . . 23 4.2 Variation 2 . . . 23 4.2.1 Description . . . 23 4.2.3 Protocols . . . 23 4.2.2 Interactions . . . 24 4.2.4 Implementation . . . 26 4.2.5 Comments . . . 27 4.3 Variation 3 . . . 28 4.3.1 Description . . . 28 4.3.3 Protocols . . . 28 4.3.2 Interactions . . . 29 4.3.4 Implementation . . . 30 4.3.5 Comments . . . 31 4.4 Variation 4 . . . 32 4.4.1 Description . . . 32

(5)

4.4.3 Protocols . . . 32 4.4.2 Interactions . . . 33 4.4.4 Implementation . . . 35 4.4.5 Comments . . . 37 4.5 Variation 5 . . . 38 4.5.1 Description . . . 38 4.5.3 Protocols . . . 38 4.5.2 Interactions . . . 39 4.5.4 Implementation . . . 41 4.5.5 Comments . . . 43 4.6 Scenario Review . . . 43

5 Quote Request Scenario 45 5.1 Original Requirements . . . 45

5.2 Design Issues . . . 46

5.3 Specifications . . . 47

5.3.1 Buyer - Supplier Interactions . . . 47

5.3.2 Supplier - Manufacturer Interactions . . . 48

5.4 Protocols . . . 49 5.4.1 Buyer - Supplier . . . 50 5.4.2 Supplier - Manufacturer . . . 51 5.5 Implementation . . . 52 5.5.1 Ports . . . 52 5.5.2 Location . . . 52 5.5.3 Supplier . . . 52 5.5.4 Buyer . . . 60 5.5.5 Manufacturer . . . 64 5.6 Testing . . . 65 5.7 Comments . . . 68 6 Evaluation 70 6.1 SJ Comparative Evaluation . . . 70 6.1.1 Advantages . . . 70 6.1.2 Disadvantages . . . 71 6.1.3 Comments . . . 71 6.2 SJ Protocols Evaluation . . . 72 6.2.1 Correctness . . . 72 6.2.2 Scalability . . . 72 6.2.3 Difficulty . . . 73 6.3 Project Evaluation . . . 73

7 Conclusions and Future Work 75 7.1 Conclusions . . . 75

7.2 Future Work . . . 76

A Methods 78 A.1 Buyer’s Sort Method . . . 79

(6)

Chapter 1

Overview

1.1

Introduction

Web Services are rapidly increasing in complexity and range due to their wide applicability to internet users and businesses, and the use of XML (Extensive Markup Language) formalizing the description of data exchange. Recently, an effort has been made to control communication between web services with the introduction of new methods such as standardised Business Transaction Proto-cols. Session-Based programming uses a typing language to achieve that control and is said to be highly suitable for programming web service communication. This project aims to explore the concept through the language Session-Java.

Business transactions in traditional software engineering are understood to be entities with a short life spam operating in a closely coupled context. They are designed for successful completions, without complications such as loss of data arising during exchange. Hence, with minimal control, thousands of trans-parent transactions can occur within a system every second without troubling the programmer. The smooth operation of interaction between web services is, however, much harder to achieve. The reason behind that is that when we try to extend the concept of traditional transactions to a loosely coupled environment such as the web we find that they’re unsuitable.

The situation becomes even harder if we’re dealing with applications of a long life spam, running for hours or even days and almost inevitably resulting in a deadlock. Business to business interactions often require such long-lived transactions. A need arises for new transaction implementations, more suitable for the web. Protocols already exist but the recent blossoming of web services, combining more and more distributed services makes this a very important topic in today’s industrial world.

In this project we will be focusing on Session-Based Programming, a method of controlling process interactions (represented by sessions). It works by speci-fying the intended process transaction protocol using session types and imple-menting the interaction using session operations. The session implementations will then be verified with the session specifications to guarantee a correct

(7)

imple-mentation and secure communication between web services. Session-Java (SJ) is an extension to Java implementing Session-Based Programming. The language is still under development but a stable version of it exists and by programming in it we’re planning to create several real life scenarios of web businesses in-teracting. Those scenarios can be used by the SJ designers as programming paradigms or compared with similar implementations in other languages such as for example the Java RMI.

We will focus onbusinessscenarios but this should be a wide enough subspace to allow us to test different aspects of the language. This will be the first time that business communication of a sufficient depth will be implemented in SJ, so our scenarios aim to test multiple aspects of the language and enable us to identify its pros and cons. Our priority is that by the end of the project we will have produced complicated programs in SJ. Through these we’re aiming to confirm the suitability of Session-Java as an implementation of business to business transactions. We want to explore the robustness of the language and the scalability as scenarios vary in size but also complexity. In addition we will be looking for things such as ease of programming in SJ, any limitations, bugs or non-implementable scenarios.

In fact, SJ is closely tied to the Web Services Choreography Working group[3], currently designing the Web Services Choreography Description Language[1] (WS-CDL) aimed specifically at interactions amongst web services. The plan is that SJ will be used as part of the implementation technologies for the language. Like UML with Java, this could possibly be directly translated to SJ code, and hence generate code skeletons. If, however, there exist any non-implementable scenarios in SJ then they will have to be overcome before that stage is reached. Results produced through this project could possibly have a direct impact on the future development of SJ.

1.2

Contributions

• Through our project we have provided with some interesting documented scenario variations (Chapter 4) to the TicketAgency example found in the “Web Services Choreography Description Language: Primer 1.0”[1] paper. We have shown how they are implemented using session programming and SJ. An analysis of the tradeoffs in design choices for the scenarios and their implementations in SJ is also included.

• We have also provided an implementation of the quote request use case found in “Section[3.1.2] C-UC-002 - Quote Request” in the “Web Services Choreography Requirements”[2] paper (Chapter 5).

• Finally we hope that this report will provide some useful feedback to the SJ designers from a users viewpoint.

(8)

1.3

Structure of Report

• We will first analyze the key work that this project is based upon in Chap-ter 2. This includes the key concepts of Session Programming (Section 2.1) and the core language MOOSE (Section 2.2). We will then introduce Session-Java and explain the main syntax and session types (Section 2.3). • An introductory example will follow where we will also exhibit the new additions to SJ that have happened either just before, or during the course of this project (Chapter 3).

• We will then move to implement variations to a “TicketAgency” Business scenario, including a step-by-step analysis of the process of transforming each scenario into an SJ protocol and then using SJ types to implement it (Chapter 4).

• The main deliverable of the project is the implementation of the “Sec-tion[3.1.2] C-UC-002 - Quote Request” use case in paper “Web Services Choreography Requirements”[2] in SJ (Chapter 5).

• An evaluation of both SJ and the project (Chapter 6) and conclusions and potential further work (Chapter 7) conclude the report.

(9)

Chapter 2

Background

One of the main challenges of concurrent programming is the communication be-tween different computational processes. This holds regardless of whether we’re dealing with concurrent processes executed sequentially on a single processor or processes exchanging information through the web as part of a business trans-action. To begin to understand Session-Java, we have to explore the theoretical works that are fundamental to its implementation.

2.1

Session Programming

In the “Language Primitives and Type discipline for structured communication-based programming”[5] paper the authors introduce a structuring method for communication-based concurrent programming. What is characteristic about this method is the use of a type discipline as an fundamental tool used to ensure compatibility of interaction patterns between processes throughout com-munication. Following is an overview of the main ideas of the paper proposal:

• The definition of asessionas a chain of dual interactions. The collection of sessions is a program. A session would be allocated a particular private port called achannel, and all interactions belonging to the session would occur within that channel.

• Value passing,label branchinganddelegationas communication primitives. – Value Passing is synchronous message passing (standard as in other

process calculi)

– Label branching is a “purified” form of method invocation (not in-cluding value passing)

– Delegation is dynamic channel passing from one process to another, allowing for the structured distribution of a single session among different processes.

• The type discipline for the above communication primitives.

Remarks The regular constructs in concurrent programming (parallel compo-sition, name hiding, conditional and recursion) are also provided in the proposal

(10)

without any noted alterations. Note that the channel is different from the usual port number and this was a conscious design decision by the authors to make the programs have an explicit logical structure.

This proposal aims to take advantage of the fact that most errors in communication-based programming could be caught using this type discipline and this is the essential argument for using Session-based Programming, as we will see later.

Even though the typability of our programs might give an overhead compu-tational cost in implementation, by comparing interaction patterns of processes we can detect potential incompatibility before we even engage in a transaction. Also, an additional high-level layer of protection is automatically created.

Enforcing types in program interactions introduces the concept ofdual com-munication patterns. These are simply compatible patterns of data exchange between the programs. For example, the dual of a procedural call pattern of (input string - output double) would be (output string - input double).

In the paper the authors note that in it’s implementation, the proposal should be used by embedding the communication constructs in the various program-ming languages used over the web to ensuring the different languages are com-patible. To this day, however, the concept has not reached that stage.

(11)

2.2

Merging Object Orientated with Session-Typed

programming

MOOSE, “a multi-threaded object oriented core language augmented with ses-sion types, which supports thread spawning, iterative sesses-sions, and higher-order sessions”, is a language proposed in the paper “Session Types for Object-Orientated Languages”[4]. The authors analyze how the concept of Session-typed programming can be incorporated to object orientated languages and produce a complete design of a language that incorporates the concept, in-cluding its syntax, operational semantics and type system. Here are the main characteristics of MOOSE briefly described:

• The MOOSE programming style is similar to popular object orientated languages

• Thread spawning, higher-order, conditional and iterative sessions are all supported in order to provide the expressivity of common scenarios from concurrent programming, session type, and W3C[3] (Web Choreography Group) environments.

• Special attention was given to guarantee type preservation. Linear usage of channels was enforced

• Threads never starve or deadlock during sessions, and the liveness property is maintained

Remarks As we discussed earlier, deadlocks are an important consideration when dealing with long-lived transactions that occur through the web. The liveness property in threads is a remarkable aspect of MOOSE, that eliminates the deadlock possibility.

For that property to hold, however, linear usage of channels has to be enforced A critical issue for a full implementation of MOOSE would be the range of scenarios programmable in it, i.e. whether the enforcement of linear usage of channels would result in a substantial sacrifice of implementable scenarios. This is going to be something we will be thoroughly examining in this project in Session-Java.

(12)

2.3

Session-Java (SJ)

2.3.1

Main Properties

We have seen the fundamentals of Session-Typed programming as well as the major reasons behind it’s suitability. We have briefly seen that there have been efforts to incorporate this to Object Orientated programming and the main desirable properties that would arise from this merge. Session-Java is the first full implementation of a language for session-based distributed programming. The essential aims of MOOSE such as linear usage of channels and liveness are maintained in Session-Java. Here are the main properties of SJ:

• Interaction patterns calledprotocolsare specified in the using the typing language and implemented using session operations

• Runtime validation of protocols using the typing language at method ini-tialization. This means that for any interacting programs SJ ensures that their protocols aredual, according to the concept of dual communication patterns described above.

• Verification between the specified protocols with the implementation of the protocols. The specification of the protocols uses the session typing lan-guage and is written prior to the implementation uses session operations. The compiler framework compares the specification with the implementa-tion statically and programs only compile if the two are consistent. • Support of session abstraction over TCP. Session operations are mapped to

lower level communication primitives by the compilation-runtime frame-work.

SJ programs have a .sj extension. SJ includes it’s own compiler framework which means that producing a program in SJ would be compiled using the SJ (Polygon) compiler to create a class file like traditional Java but also the Java file.

Although a paper on SJ has already been published, the language is still under research and development.

2.3.2

Using SJ

Like the authors in “Session-Based Distributed Programming in Java”[6], we will illustrate the SJ syntax using the WS-CDL[3] use case found in “Web Services Choreography Requirements”[2]. This is an example of a Customer, Agency, Service scenario described below:

1. Customer begins an order session (s) with Agency specifying a desired journey and receiving a price for it from Agency. The customer can repeat this interaction indefinitely for different journeys.

2. Customer either accepts or rejects price from agency 3. If customer accepts price

(a) The agency has to communicate with service and confirm the trans-action.

(13)

(b) Service opens a session (s’) with customer and receives his address to return a date of dispatch for the travel tickets. The customer is unaware that agency has delegated the session as he’s using the same session channel.

4. If customer rejects price then the order session finishes

As the paper gives a very analytical view of the language and is the only source of documentation for programming in SJ, we will follow the approach of the authors, and provide a more stripped down description of the major attributes of SJ.

The protocols for the order session (between Customer and Agency) are specified below asplaceOrder, which describes the interactions from Customer’s side, and acceptOrder, from Agency.

protocol placeOrder {

cbegin.

// client begins session.

![ // can iterate:

!<String>. // send String

?(Double) // receive Double

]*.

!{ // Select one of:

ACCEPT: !<Address>.?(Date),

REJECT: }

}

(A) Order protocol: Customer side.

protocol acceptOrder {

sbegin.

//server begins session

?[

?(String). !<Double> ]*.

?{

ACCEPT: ?(Address).!<Date>,

REJECT: }

}

(B) Order protocol: Agency side.

• To begin with, the!<..> indicates sending something so in this case !<

String>in (A) means that that the customer would have to send a string.

• The ?(...) indicates receiving something and in this case ?(Double) in (B) means that the service would receive the string.

• [..]*indicates iteration.

• ![..]*in A indicates that the iteration occurs under the customer’s initia-tive while?[..]*in B indicates that the iteration is not under the agency’s initiative.

• !{...}in A means that the customer has a decision to make while?{...}in B shows agency that the other party will decide which branch to choose. In our examples the customer’s options are ACCEPT and REJECT. In case ACCEPT is chosen the customer sends an address, receives a date and the session terminates, while in case ofREJECTthe session terminates there. Notes The two protocols are dual as is the spirit of Session-Typed program-ming. Also, there is no keyword for the ending of the session, but that is estab-lished implicitly. The different inputs are separated by dots except in the case of branching where the options are separated by commas. The specification of the protocols will be followed by their implementation using session operations.

(14)

begin c.request(),ss.accept() // Session initiation.

!<C> s.send(obj) // Object ‘obj’ is of type C.

!<S> s1.send(s2) // ‘s2’ has remaining contract S.

?(T) s.receive() // Type inferred from protocol.

!{L:T,..} s.outbranch(L){...} // Body of case L has type T, etc.

?{L:T,..} s.inbranch(){...} // Body of case L has type T, etc.

![T]* s.outwhile(boolean expr){...} // Outwhile body has type T.

?[T]* s.inwhile(){...} // Inwhile body has type T.

Figure 2.1: Session operations and their types (Copy from SJ paper[6]) Session sockets After declaring the protocols for the intended interactions, the next step is to createsession socketsfor initiating sessions and performing session operations. There are three main entities:

• Session server socket of class SJServerSocket, which listens for session requests, accepting those compatible with the specified protocol.

• Session Serviceof classSJService, which specifies the address of a session server socket and the type of session it accepts; and

• Session socketof class SJSocket, which represents the endpoint (client or server) of a session channel, through which communication actions within a session are performed. A session socket is used by a client to request the establishment of a session to a server.

The session sockets and session server sockets correspond to standard socket programming equivalents, but include their associated session types and hence provide different properties.

In the first version of SJ, client sockets were tied to a session server-address at creation, and could only make requests to that server. Now, however, the SJ socket is not required to be final and can be passed to someone else, as long as it loses its value when it does. This will be analysed further later. What is of great significance is that there do not exist multiple occurrences of the same socket, as this would infringe the linearity property.

Session server sockets accept server requests only if the requesting client’s pro-tocol is compatible to the server. Upon acceptance, the server will spawn it’s own session socket that will correspond to the opposing endpoint of the request-ing client socket, thus initiatrequest-ing the session. Any messages passed durrequest-ing the session will have to be typed as per the protocols of the session.

Session server sockets Programs that offer session services, like Agency, use a session server socket to accept session requests:

SJServerSocket ss_ac = SJServerSocketImpl.create(acceptOrder,port);

Once the server socket is opened, the server can accept a session request by, s_ac = ss_ac.accept();

where s ac is an uninitialized SJSocket variable. The accept operation blocks until a session request is received. The server then validates that the protocol requested by the client is compatible with that offered by the server and returns a new session socket, i.e. the server-side endpoint.

(15)

Session services and session sockets.

A session service identifies a server by its IP address and TCP port. At the Customer, we set:

SJService c_ca = SJService.create(placeOrder, host, port);

A service inherits the type of the client side, in this case placeOrder. Services can be communicated to other parties, allowing them to request sessions with the same server. Hence, inheritance can occur from both the server and the client. Customer usesc cato create a session socket:

SJSocket s_ca = SJSocketImpl.create(c_ca);

and request a session with Agency: s_ca.request();

Assuming the server socket identified by c ca is open, request blocks until Agency performs the corresponding accept. Then the requesting and accept-ing sides exchange session types, independently validate compatibility, and if successful the session between Customer and Agency is established. If incom-patible, an exception is raised at both parties (see ‘Session failure’ below). Send and receive operations

After the session has been successfully established, the session socket s ca be-longing to Customer (respectively s ac for Agency) is used to perform the ac-tual session operations according to the protocolplaceOrder. Static session type checking ensures that this contract is obeyed.

The basic message passing operations, performed by send and receive, asyn-chronously communicate typed objects. This mean that there are no restrictions on the sequence of operations. For example, we can have several sends before a receive and vice versa.

s_ca.send("London to Paris"); // !<String>.

Double cost = s_ca.receive(); // ?(Double)

Iteration

Iteration is abstracted by the two mutually dual types written ![...]* and

?[...]*. [...]* expresses that sequence of interactions in[...] may be iter-ated zero or more times. These types are implemented using theoutwhile and inwhile operations, which can together be considered a distributed version of the standard while-loop. In our example,placeOrder,![!<String>.?(Double)]*, and its dual type at Agency is implemented as follows.

(16)

boolean decided = false;

... // Set journey details.

s_ca.outwhile(!decided) {

s_ca.send(journeyDetails);

Double cost = agency.receive() ;

... // Make decision or

... // retry with different

details } s_ac.inwhile() { String journeyDetails = s_ac.receive(); ... // Calculate cost.

s_ac.send(price); }

Like the standard while-statement, theoutwhileoperation evaluates the boolean condition for iteration (!decided) to determine whether the loop continues or terminates. This decision is communicated to the program running theinwhile (in this case, from Customer to Agency), synchronising the control flow between two programs. This is why theinwhileloop has no condition. In chapter??we we also introduce recursion in SJ.

Branching

InplaceOrder, Customer’s protocol dictates!{ACCEPT: !<Address>.?(Date), REJECT:

}, with! meaning that customer is the program making the decision. Customer either selects ACCEPT, leading into a (send address - receive data), or selects REJECT which terminates the session.

The branching happens usingoutbranchandinbranch. These, like the iteration case with while loop, can be considered a distributed switch-statement. Here is the implementation in our example:

if(want to place an order) {

s_ca.outbranch(ACCEPT) {

s_ca.send(address);

Date dispatchDate = s_ca.receive() ;

}

} else { // Don’t want to order.

s_ca.outbranch(REJECT) { } } s_ac.inbranch() { case ACCEPT: { ... } case REJECT: { } }

The condition of the if-statement in Customer (whether or not Customer wishes to purchase tickets) determines which branch will be selected at runtime. The body ofACCEPTin Agency is completed in ‘Session delegation’ below.

Session fail Sessions are implemented withinsession-tryconstructs: try (s_ac, ...) {

... // Implementation of session ‘s_ac’ and others.

} catch (SJIncompatibleSessionException ise) {

... // One of the above sessions could not be initiated.

} catch (SJIOException ioe) {

... // I/O error on any of the above sessions.

(17)

This results in graceful failure if a run-time error occurs, and results in useful input from the compiler.

Session delegation.

If Customer is happy with one of Agency’s quotes, it will select ACCEPT. This causes Agency to open a second session with Service, over which Agency dele-gates to Service the remainder of the conversation with Customer, as specified in

acceptOffer. After the delegation, Agency relinquishes the session and Service will complete it. Since this ensures that the contract of the original order session will be fulfilled, Agency need not perform any further action for the delegated session; indeed, Agency’s work is finished after delegation.

At the application-level, the delegation is exposed to only Agency and Service; Customer will proceed to interact with Service unaware that Agency has left the session, which is evidenced by the absence of any such action inplaceOrder. The session between Agency and Service is specified by the following mutually dual protocols:

protocol delegateOrderSession {

begin.!<?(Address).!<Date>> }

protocol receiveOrderSession {

begin.?(?(Address).!<Date>) }

Delegation is abstracted byhigher-order session types where the specified mes-sage type is itself a session type; in this example, ?(Address).!<Date>. The message type denotes the unfinished part of the protocol of the session being delegated; the party that receives the session will resume the conversation, ac-cording to this partial protocol.

In terms of implementation, delegation is naturally represented by sending the session socket of the session to be delegated. Continuing our example, Agency can delegate the order session with Customer to Service by

case ACCEPT: {

SJService c_as = ... // delegateOrderSession.

SJSocket s_as = SJSocketImpl.create(c_as);

s_as.request();

s_as.send(s_ac); // Delegation: Agency has finished with s_ac.

}

and Service receives the delegated session from Agency by

SJServerSocket ss_sa = SJServerSocketImpl.create(..., port)

SJSocket s_sa = ss_sa.accept();

SJSocket s_sc = s_sa.receive(); // Receive the delegated session.

Service then completes the session with Customer. Address custAddr = s_sc.receive();

Date dispatchDate = ... // Calculate dispatch date.

s_sc.send(dispatchDate);

As SJ is a project that is still under development, it is continuously being changed. Some notable changes at the time of writing is the renaming of the ServerAddress into SJService. Also, in protocol definition, begin has been re-placed by sbegin for server protocols and cbegin for client protocols. Another change in SJ is the introduction of the termnoalias.

(18)

Noalias Objects

If an object is defined as noalias, it only has one reference to it. This would mean that no pointers for that object can exist.

public void passing {

noalias String m = ‘‘Legal operation’’;

String n;

n = m; // m is now null

}

Correctly passing a noalias object

public void illegal {

final noalias String m = ‘‘

Illegal operation’’;

String n;

n=m; }

Illegal operation

We see from the above example that passing the noalias object from variable m to n would make m null. finalnoalias objects behave as final objects regularly do; their value cannot be altered. Note that protocol and SJService objects can only be declared as final noalias. SJSocket objects on the other hand have to be declared as noalias, but not necessarily final. These restrictions have been set to ensure that the linearity of channel usage, the advantages of which were briefly discussed in the MOOSE language section.

Protocol Reference

A completely new element is the ability to refer to protocols from within other protocols. This protocol can now be referred to from within another protocol using the operator @. Also, the dual of the protocol can be automatically be

calculated and referred to using the ˆ operator. Here is an illustration of this concept.

final noalias protocol rp

{

sbegin.?(@(p)).?(String) }

Receiving protocol

final noalias protocol rdp

{

sbegin.?(^(p)).?(String) }

Receiving dual of protocol

Note that the ?(String) operation has only been included to illustrate how SJ provides the functionality to extend the called protocol p. We can also see that p is used in the example in high order message passing i.e. to describe a delegation. Since the protocol p is received in both examples here, protocols rp and rdp would be inside programs that inherit the session as opposed to a program that delegates it. These changes to SJ will be further analysed in the upcoming sections.

(19)

Chapter 3

The two SJ versions used in

this project

3.1

Overview

My first encounter with SJ was via the quickstart scenario created by Ray-mond Hu[7]. In this scenario we have a server program called Alice and a client program called Bob that establish a session and interact by sending a String to each other.

The version of SJ used to construct these two programs was a more stable version that the one now under development. This was also the version that I originally used to program in SJ, as the stability it provided me gave me the opportunity to familiarize myself with the fundamental concepts of the language and make my own mistakes, without having to worry that a bug in the language was responsible for any problems with the programs.

e.g. an error message from the compiler.

Note however, that this stable version had limitations in the programs which could be created in it as some language constructs had not been implemented in it. This was the reason why when the scenarios I was to implement be-gan to get more complicated, I had to switch between the two versions. I will be illustrating the differences between the two versions through the quickstart scenario.

3.2

Quickstart Scenario

This scenario is very basic but once again illustrates the duality of two protocols: protocol BobToAlice {

begin.?(String).!<String> }

Quickstart protocol: Client side.

protocol AliceToBob {

begin.!<String>.?(String) }

(20)

3.3

The differences in the two versions

In this version of SJ, we notice that both protocols are initiated with abegin.

command. However, it was later decided by the programmers that the protocols for the client and server programs should be distinguished and this was imple-mented by using:

sbegin. //server protocol

cbegin. //client protocol

to initialise the two protocols respectively (as described before). Another point is that while the protocol used to be defined as: protocol p

we now define it as: final noalias protocol p

The final keyword is the same as the regular JAVA final and simply means that the protocol can never be re-defined at any point throughout the program. Thenoaliaskeyword has been created by the SJ developers and it means that “there can never exist more than one” versions of the protocol, as shown in subsection (2.3.2).

These two keywords ensure that the only operators which can be used to pass a reference to a protocol are @ and ^ and that the protocol cannot be passed to a variable by value (noalias keyword), and also that once a reference to a protocol exists, the protocol cannot change, which would create discrepancies between different references (final keyword).

It is also clear to see that for any protocol, the client side of the protocol is fully defined by the server side and vice versa. In the new version of SJ, we can hence only define one side of the protocol in a specified class (in this case I have arbitrarily chosen the server side) and use the @ and ^ operators (Subsection 2.3.2, Protocol Reference) to define both protocols in their respective classes without ever having to exclusively define the dual of the protocol.

As an implemented illustration:

public final noalias protocol

AliceToBob {

sbegin.!<String>.?(String) }

Quickstart protocol: Server side. located in class Protocols

We define a new class Protocols and insert one of our protocols in there. We can now define the two protocols as follows:

final noalias protocol

BobToAlice {

^(Protocols.AliceToBob)

//dual reference to AliceToBob //equivalent to BobToAlice

}

Quickstart protocol: Client side.

final noalias protocol

AliceToBob {

@(Protocols.AliceToBob)

//direct reference to AliceToBob

}

Quickstart protocol: Server side.

Even though the quickstart is quite a basic protocol, one can see the benefits this would bring about:

(21)

• This would save a programmer a lot of time from defining the dual of a protocol, which would be unnecessary.

• During development, in a big program which includes complicated inter-actions it would be much easier for a programmer to alter the protocols once from a central class (such asProtocols), rather than have to change them both at the client and the server classes.

• Finally, it is quite intuitive in terms of object-orientated programming to have the full protocols in a separate class, which also rids the client and server classes of big bunches of code that do not form part of the mainstream code of the programs, making them easier to scan through and disambiguous.

Moving on to the implementation of the protocol, and starting with the server side, we have:

SJServerSocket ss = null;

The definition of the SJServerSocketremains as it was previously shown (Sec-tion: 2.3.2, Session Server Sockets), however the implementation has been changed to:

final noalias SJServerSocket ss;

Just like with the protocols, the server socket cannot be altered or referenced to. This makes sense, we wouldn’t want two server sockets listening for the same session request. Also, changing the server socket at any point throughout our program could bring up many undesired complications.

In Alice, we proceed with setting up the server socket to listen for potential incoming sessions at a specified port (say 1234), using the AliceToBob protocol:

try {

ss = SJFServerSocket.create(AliceToBob, 1234); ...

There used to be two ways in which the server socket could be created, using ss = SJFServerSocket.create(AliceToBob, 1234); or

ss = SJRServerSocket.create(AliceToBob, 1234);

These two differ only in how they handle delegation. Suppose a session exists between party S1 and C, and we delegate the session from party S1 to S2. The SJF uses the forwarding protocol in which any lost messages from C are received by S1, they are forwarded to S2 before the connection C-S1 is substituted by C-S2. The SJR uses the resending protocol in which lost messages are cached by C and resent to S2 after the new connection C-S2 is established.

However, we no longer need to worry about these two types. The details of the delegation are now being modularised within the SJ Runtime in a way transparent to the programmer. Once again the syntax has now changed to :

try (ss){ //try(ss) as opposed to a regular try statement

ss = SJServerSocketImpl.create(AliceToBob, 1234); ...

(22)

Up to this point, Alice (our server) has created a server socket and is ready to listen to any incoming requests. The way we proceed is by creating anSJsocket, which, as described in (subsection 2.3.2, Session sockets) represents an endpoint of the session channel:

SJSocket s = null;

try (s) {

s = ss.accept(); ...

Now Alice is listening on the port 1234 and is ready to proceed with the protocol, which is implemented much as explained in subsection 2.3.2. The new imple-mentation of theSJSocket is almost the same for the server with the exclusion of the= nullpart, and including final noalias:

final noalias SJSocket s;

try (s) {

s = ss.accept(); ...

I will now proceed to analyse key points in Bob (our client). Firstly, the client must create anSJServicetaking parameters the protocol, host and port:

SJServerAddress c =

SJServerAddress.create(BobToAlice, "localhost", 1234);

This has now been changed to: final noalias SJService c =

SJService.create(BobToAlice, "localhost", 1234);

//SJService = SJServerAddress

We note that other than the renaming of SJServerAddress toSJService, there are no differences to the properties of the two at least as far as the programmer is concerned. The reasons for requiring SJService to befinal noalias are the same for SJServerSocket.

Bob would then proceed to create an SJSocket, the opposing endpoint to the session channel with respect to theSJSocketin Alice:

SJSocket s = SJFSocket.create(c);

try (s) {

s.request(); ...

Bob is now ready to proceed with the protocol implementation just as described in the background section (2.3.2). The s.request(); has been slightly altered and in the new version it would be created as follows:

final noalias SJSocket s; // no .create(c) command

try (s) {

s = c.request(); // define which service c we

... // are using by c.request()

where c was the SJServicecreated before. This change is because, just like the

SJServerSocket, there is only one type ofSJSocketnow.

A few minor changes were also made to the names of the SJ packages and the commands to compile and run SJ programs, as illustrated below:

(23)

//To compile a program:

bin/sjc ...

//To run a program:

bin/sj ...

//Imported libraries

import sj.runtime.*;

import sj.runtime.net.*;

Old Version

//To compile a program:

bin/sessionjc ...

//To run a program:

bin/sessionj ...

//Imported libraries

import sessionj.runtime.*;

import sessionj.runtime.net.*;

(24)

Chapter 4

The TicketAgency Scenario

The TicketAgency Scenario, as described in section (2.3.2), covers a lot of cen-tral aspects of SJ, as well as Session-Based Programming. The scenario has a protocol very common for business interactions and so we decided to produce a number of variations to the scenario, increasing in complexity and more and more diverging from the original scenario, in order to test different properties of SJ.

4.1

Variation 1

In words the first variation is as follows:

4.1.1

Description

1. Customer begins an order session (s) with Agency specifying a desired journey and receiving a price for it from Agency.

(a) The customer can repeat this interaction indefinitely for different journeys.

(b) Customer identifies which journey is desired through the use of out-branch

2. Customer either accepts or rejects price from agency 3. If customer accepts price

(a) The agency has to communicate with service and confirm the trans-action.

(b) Service opens a session (s’) with customer and receives his address to return a date of dispatch for the travel tickets. The customer is unaware that agency has delegated the session as he’s using the same session channel.

4. If customer rejects price then the order session finishes

What has been altered from the original scenario is that the customer now selects a journey, whereas in the original code the same interaction took place

(25)

regardless of what the first !<String> sent was. In a different language, the programmers first response could be to program Agency to receive the desired journey from the customer and then depending on what was received, send a corresponding price. i.e.

String travDetails = s_ac.receive();

Double cost = getPrice(travDetails);

//Method getPrice(String d) determines value to be sent

s_ac.send(cost);

Protocol implementation

We would then have multiple if statements to branch between the different types of travel methods:

private Double getPrice(String travelMethod) {

...

if(travelMethod.startsWith("Bus")){ ...

}

else if(travelMethod.startsWith("Train")){ ...

}

else if(travelMethod.startsWith("Plane")){ ...

}

Function getPrice(String t)

4.1.3

Protocols

We can however incorporate this decision in our protocol through the use of outbranch. We would then alter the scenario to:

protocol p_ac { begin. ?[ ?(String). !<Double> ]*. ?{

ACCEPT: ?(Address).!<Date

>,

REJECT: }

}

Original scenario for Agency

protocol p_ac { begin. ?[ ?{ TRAIN: BUS: PLANE: }.!<Double> ]*. ?{ ACCEPT: ?(Address).!< Date>, REJECT: } }

(26)

4.1.2

Interactions

Customer Agency Service

s Double accept Repeat until Customer is satisfied Address s’ ?(Address).!(Date) Date s reject s Customer Agency T s lab s A B A B A B A B A

Arequests session s with B

Asends type Tto B

Acan choose to repeat this part of the session

Aselects labat B Aand Bclose s s’ 1a 2 3a 3b 4 2 Train Plane Bus 1b

Figure 4.1: Overview of interactions for variation 1

An equivalent change, omitted here would happen to the scenario for the cus-tomer. The delegation pattern has not been altered in any way and so delegation from Agency to Service remains the same, both in protocol and implementation, as the original scenario.

Although there aren’t any real benefits of this change in protocol, the situation would be quite different if different interactions took place depending on the type of ticket. This would be quite likely if we were dealing with a real life situation. For example, if we were to include a discount to the customer pro-vided he is eligible for it, a train ticket might require a Railcard Identification number while an aeroplane ticket might require a frequent flyers card. The use ofinbranch - outbranchprovides a synchronized decision by the two parties to follow a specified set of interactions and saves a lot of work.

Figure 4.2 illustrates the interactions that would possibly have to take place in a different language in order to achieve the same effect. We note that de-pending on the underlying transport mechanism the final confirmation message might not be required.

4.1.4

Implementation

Changes in implementation for this variation would only occur in Customer and Agency. We enter the String order as an argument to the class Customer who then decides how tooutbranch. This was programmed on the first version of SJ. Here are the outbranch statements below:

(27)

Customer Agency

String

Receive and decipher Agency’s choice

Boolean Integer

Receive and decipher acknowledgement message

Prepare for upcomming collaboration and send boolean to

confirm Send method of travel

Receive method of travel and choose how to proceed

Send Integer corresponding to choice

Figure 4.2: Potential message exchanges in a different language

if(travelMethod.startsWith("Bus")) {

s_ca.outbranch(BUS) {

System.out.println(‘‘Requested Bus Service’’);

} }

else

if(travelMethod.startsWith("Train")) {

s_ca.outbranch(TRAIN) {

System.out.println(‘‘Requested Train Service’’);

} }

else

if(travelMethod.startsWith("Plane")) {

s_ca.outbranch(PLANE) {

System.out.println(‘‘Requested Plane Service’’);

} }

Double cost = s_ca.receive();

//In new version:

//Double cost=(Double) s_ca.receive();

Customer choice reflected through outbranch case Double cost; s_ac.inbranch() { case(BUS): { cost = getCost(‘‘Bus’’); } case(TRAIN): { cost = getCost(‘‘Train’’); } case(PLANE): { cost = getCost(‘‘Plane’’); } }

s_ac.send(cost);

Agency receives customer choice and acts accordingly

While in the old SJ version casting of the receiving attribute was not obligatory, in the new version it is and so the statement in Customer would have to be:

(28)

4.1.5

Comments

This program is an example of nested branch statements, as the customer out-branches within the [...]* loop. SJ can cope with this and no errors were brought up during the compilation of Agency and Customer, which means that the compiler correctly opted that the two protocols and their implementations match.

4.2

Variation 2

4.2.1

Description

1. Customer begins an order session (s) with Agency specifying a desired journey and receiving a price for it from Agency. The customer can request a train or aeroplane journey.

2. Agency opens the session s1 with service(either train, or aeroplane agent)

and delegates to sub-agent through s1 the interactions with Customer remaining for s. Service then sends the price for the journey to Customer.

3. Customer either accepts or rejects price from Service

4. If an offer is accepted, Customer sends a delivery address, and Service replies with the dispatch date for the purchased tickets. The transaction is now complete.

5. Customer cancels the transaction if no quotes were suitable and the session terminates.

Our second variation is regarding the session delegation from the Agency to the Service. In this case the Agency receives the journey type from the Customer and instead of replying with a price, it delegates the session to the corresponding Service straight away. The responsibility of sending the Customer a price is now upon the service.

In this situation and unlike the first variation, we will not be using inbranch

- outbranch for this choice by the Agency. The Agency will instead keep the decision transparent to the customer, which is perhaps more appropriate as the customer should not be concerned with the inner workings of Agency. This capability is provided by SJ.

4.2.3

Protocols

To exhibit this property, we have chosen to keep the protocols between Customer and Agency the same as the original scenario. The only difference will be in the Customer-Service protocol:

(29)

4.2.2

Interactions

Customer Agency Service A

s String Double accept Address [airoplane]s’ Date s reject s T s d s A B A B A B A B A

Arequests session s with B

Asends type Tto B

Acan choose to repeat this part of the session Aselects dat B Aand Bclose s 4 Identify request type (Airoplane/ Train/Bus) 1 2 P(A) = !<Double>. ?{ accept: ?(Address).!<Date>, reject: } Service T [train]s’ Customer Service (A|T) String.P(A) Session s’

[o] s’ If o then Arequests session s with B

A B

3

3 5

(30)

//implemented in new SJ version

final noalias protocol p_as

{

//Send remaining scenario //between Customer and Agency

cbegin. !< !<Double> .?{ ACCEPT: ?(Address).!<Date>, REJECT: } >

//Then send customer order

.!<String> };

(AS) Agency - Service Protocol

//First define the //high order message

final noalias protocol p

{ !<Double>. ?{ ACCEPT: ?(Address).!<Date>, REJECT: } } //Then include it //in the scenario

final noalias protocol p_sa

{

sbegin.?(@(p)).?(String) }

(SA) Service - Agency Protocol

In fact the !<String> corresponding to passing the customer order is only re-quired in case the order contained any additional information other than the type of journey, that the Service requires in order to reply with a price. As a reminder to the reader we note that the

!< !<Double> .?{

ACCEPT: ?(Address).!<Date>,

REJECT: }

>

in (AS) corresponds to a high order message. The!<...> means that it is the Agency that is passing the high order message and everything inside it is the protocol of the session that the Service should establish with the Customer. In (SA) we see a subtle way of defining a protocol containing high order messages by first defining them and then including them in the protocol.

The Service - Agency protocol is in this case included in both the ServiceT and ServiceA classes (Train and Aeroplane services respectively) but just as in the Quickstart scenario (section 3.2), it can be included in a class Protocols and accessed by all Service classes that would use it.

(31)

4.2.4

Implementation

noalias SJSocket s_ac;

//SJSockets don’t always have to be final

try (s_ac) {

...

if(travDetails.startsWith("Train"))

{//delegate to train service that has addr_s, port_s

final noalias SJService c_as = SJService.create(p_as,

addr_s, port_s);

final noalias SJSocket s_as;

try (s_as) {

s_as = c_as.request();

s_as.send(s_ac); //Pass Remaining Protocol

//No more operations on s_ac allowed.

s_as.send(travDetails); //!<String>

} ... }

Session Delegation Implementation

Despite the fact that session delegation takes place, the program still remains very simple. Actually delegating the protocol is straightforward and only con-sists of passing the socket to service:

s_as.send(s_ac);

We have included the whole segment of code to illustrate the following point. The code below is almost identical to theifstatement above, with the exception of the address (or host) and the port parameters of the Aeroplane Service which are of course different than the ones for the Train Service.

else

{

final noalias SJService c_asa = SJService.create(p_as,

addr_sa, port_sa);

final noalias SJSocket s_asa;

try ( s_asa) {

s_asa = c_asa.request();

s_asa.send(s_ac);

s_asa.send(travDetails); }

... }

Delegating session to Aeroplane Service

However, trying to reuse code by only defining the SJServicec_asin theifand elsestatements, will not work. We illustrate below to attempts to save having to rewrite the same chunk of code.

(32)

final noalias SJService c_as;

if (...) {c_as = SJService.create(p_as, addr_s, port_s);}

else { c_as = SJService.create(p_as, addr_sa, port_sa);} ...

then the program will not compile and the compiler will bring the following error:

tests\src\michael\scenario1a\Agency.sj:67: Local variable "c_as"

multiply

defined. Previous definition at ...

because c_as was declared final. If one attempts to define c_as inside the if/else statement:

if (...) {

final noalias c_as = SJService.create(p_as, addr_s, port_s);}

else {

final noalias c_as = SJService.create(p_as, addr_sa, port_sa);} ...

the program will still not compile, this time with a different error:

tests\src\michael\scenario1a\Agency.sj:80: Could not find type,

field, or

local variable "c_as".

s_as = c_as.request(); ^--^

Despite the fact that c_as is created in both the ifand else statements (and hence any channel up to line 80), the compiler does not accept that c_as has been created.

The conclusion is that there’s no easy way out, the same chunk of code has to be repeated, when we’re dealing withfinal noaliasSJ types.

There’s not a lot of interest worth noting in service other than the fact that when receiving a high order type casting must take place and in the case of a protocol, the type of protocol must be explicitly defined:

s_sc = (@(p)) s_sa.receive();

Wherepis as defined in the protocols section (SA). This is another reason why it is good practice to first exclusively write the protocol to be delegated and then include it in the final protocol.

4.2.5

Comments

This variation to the scenario lets Agency simply act as a coordinator class, responsible for channelling the incoming session requests. This is common in many business collaborations where the different services provided by a business are all available to customers through a centralised access point.

A peculiar bug existed in class Agency and this actually happened again in a few programs later on. The class Address, which is a serializable class (used by the Customer to send his address to Service), is passed by the Agency to Service, as part of the protocol delegation. At first it seemed that an entry of Address such as:

(33)

must exist in Agency, in order for the compiler to recognise that the class Ad-dress exists, and not bring an error during compilation. This was actually noted by Raymond Hu as a potential bug. If the class Address is the first one to be compiled, however, the problem seems to disappear.

4.3

Variation 3

4.3.1

Description

1. Customer begins an order session (s) with Agency specifying a desired journey (either Train, Bus or Plane)

2. Agency opens a session (s1) with a Subagent and delegates session s along with the order sent by the Customer

3. If Subagent can provide the service (a) Subagent sends price to Customer

(b) Customer either accepts or rejects price from Subagent (c) If customer accepts price

• Subagent receives the customer’s address to return a date of dispatch for the travel tickets and the order is completed (d) If Customer rejects price the session is closed

4. If Subagent cannot provide the service, he delegates it to another subagent along with the Customer order. Go back to step 3.

5. The delegation from Subagent to Subagent continues until there are no Subagents left

We now assume a different organisational structure for the Agency, where sub-agents are more independent and can provide any Service. The Agency does not know in advance what services each of it’s subagents can provide at any given time and delegates to an arbitrary subagent. Any subagent would deal with the customer himself if possible, or delegate to the next subagent if not. We are hence dealing with a chain of delegation.

4.3.3

Protocols

The protocols for Customer and Agency remain unchanged as the original sce-nario. This is another example of how the internal workings of an organisation remain transparent to the customer. One would think that because Session-based programming involves protocols where the whole session is described, the programmer would have to go through the pain of having to change the protocol and/or its implementation for the customer, in order to reflect the way in which his session is handled. Yet again we have an example to show that this is not the case.

The change comes within the subagents. Each sub-agent has to forward the protocol:

(34)

4.3.2

Interactions

Customer Agency Subagent A

s String s1 Subagent B [unavailable] s2 Subagent T [unavailable] s3 [available] s’ [available] s’ [available] s’ String.P(A) String.P(A) String.P(A) 2 1 3 3 3 4 4 s1 s2 s3

Figure 4.4: Overview of interactions for Variation 3

Double accept Address Date s reject s T s d s A B A B A B A B A

Arequests session s with B

Asends type Tto B

Acan choose to repeat this part of the session Aselects dat B Aand Bclose s 3c 3d P(A) = !<Double>. ?{ accept: ?(Address).!<Date>, reject: } Customer Subagent (A|B|T) Session s’ s’ Session s’ occurs between A and B [o] s’ If o then Session s’ occurs

between A and B

[o] s’ If o then Arequests session s with B A B 3b 3b 3a Figure 4.5: Legend

(35)

final noalias protocol p

{ //p is reused twice

!<Double>. ?{

ACCEPT: ?(Address).!<Date>,

REJECT: }

}

final noalias protocol p_at

{ //subagent a to subagent t cbegin. !<@(p)> .!<String> }

The subagent receives p from Agency and then forwards it to the next subagent in case it cannot service the customer itself. Since no change to p occurs, the chain of delegation remains “stateless”. Any subagent receiving p does not know how many subagents p has gone through before it came to him. As far as the subagent is concerned, receiving p from the 100th subagent is the same as receiving it from the Agency themselves.

All that remains now is to implement the subagents to accept and pass del-egation. At this point we stress that our protocols for this variation are not adequate to deal with failure of the chain of subagents to deal with the cus-tomer’s request. We will do that at a latter stage.

4.3.4

Implementation

For any subagent (but the last) we have to possibilities. Either we can deal with the customer ourselves, or we have to delegate. The functiongetAvailability(

String s);checks if the subagent can deal with the customer request. if(!getAvailability(travDetails)){//Can’t deal with customer

System.out.println("Requested service unavailable in SubagentA");

noalias SJSocket s_st;

final noalias SJService a_at = SJService.create(p_at, addr_t,

port_t);

final noalias SJSocket s_at;

try (s_at) {

s_at = a_at.request();

s_at.send(s_sc); //Delegate to next in chain

s_at.send(travDetails); // Send method of travel as well

System.out.println("Delegated to: " + addr_t +" " + port_t); }

finally { } }

else{

(36)

The above piece of code is almost identical to all the subagents. This makes it very easy for the programmer. Every subagent-name can be a subclass of the class subagent. A method similar to the above can be defined in the superclass and inherited by all subagents with the correct parameters for the host and port of the subagent we are delegating to. The methodgetAvailability(String s)

could be declared abstract in the superclass.

Other than this, all we have to change in the implementation of the scenario would be the host, port of the first subagent to which agency delegates and also make a final subagent either fail gracefully or never fail to serve the customer.

4.3.5

Comments

If a company decided to change it’s inner structure and the way in which cus-tomer requests are handled, this should have minimal effect on the cuscus-tomer, which is the case with Session-Based Programming. It’s also quite intuitive for the programmer to know that if he wants to change the company inner work-ings, he doesn’t have to worry about the customer, and only edit the protocols and code within the company classes.

The fact that we can delegate the same protocol an arbitrary number of times, makes it much easier to add another subagent to the chain of delegation. The only changes that would have to be made would be informing subagents of this new addition, and informing the added subagent of where he has to delegate in case he cannot deal with the customer. It is as easy as adding a variable to a LinkedList.

In spirit with the MOOSE (section 2.2) core language, SJ not only intro-duces Session-Based Programming but also has all the benefits of an Object-Orientated language. In this case, by making an abstract class subagent, the implementation of our chain of delegation is simplified. The actual method in which to construct the super and subclasses is exactly the same as regular JAVA, with no extra effort involved. The programmer can then concentrate on implementing the individual characteristics for each subagent.

This example is more suitable for markets where the availability of services of-fered is constantly changing. This could be because of a very large customer base or due to the market being extremely volatile, with prices constantly changing. An example of such a market would be the stock market.

If we assume that the Agency distributes shares equally among it’s subagents so that they can service their respective clients, updating the Agency with the availability of any given shares would be impractical.

Also, if the Agency was to attempt to make an educated choice about where to delegate by getting the availability for a Service by each subagent, it would find it very difficult. This is because then the subagents would have to commit to the availability value that they provide the agency until it makes a decision. The effect of this action would be that they would be unable to sell any products of the particular Service in the meanwhile, and in a sector such as the stock

(37)

exchange, this could cost a lot of money. The best option would then be to delegate, as per this scenario.

A limitation of this scenario would be that the possibility of all subagents being unable to provide a quote has not been accounted for. This issue is easy to resolve when we’re using Session-Based programming and will be addressed in the next variation.

4.4

Variation 4

4.4.1

Description

1. Customer begins an order session (s) with Agency specifying a desired journey (either Train, Bus or Plane)

2. Agency opens a session (s1) with a Subagent and delegates session s along with the order sent by the Customer

3. If Subagent can provide the service (a) Subagent sends price to Customer

(b) Customer either accepts or rejects price from Subagent (c) If customer accepts price

• Subagent receives the customer’s address to return a date of dispatch for the travel tickets and the order is completed (d) If Customer rejects price then the order session finishes

4. If Subagent is not the last of the chain of delegation and cannot provide the service, he delegates it to another subagent along with the Customer order. Go back to step 3.

5. If Subagent cannot provide the service and is the last of the chain he informs the client that the Agency is unable to offer the service he has requested and the session finishes

This is an extension of the previous variation to the scenario (section 4.3) and deals with the possibility that the Agency is unable to deal with the Customer’s request. Ideally the Subagent should be able to deal with this on their own. It would become quite messy if they had to start traversing the chain of delegation backwards. We could, on the other hand, assume that each Subagent knows how to contact the Agency directly and begin a session with them but we will show that this is not necessary in this situation.

4.4.3

Protocols

Unlike previous extensions, the Customer - Agency protocol will have to be altered in this scenario. This is not because of the change in the way the Agency handles its request but due to the fact that in previous scenarios we assumed for simplification that the Agency had unlimited supply of services and could deal with all requests coming its way.

(38)

4.4.2

Interactions

Customer Agency Subagent A

s String s1 Subagent B [unavailable] s2 Subagent T [unavailable] s3 [available] s’ [available] s’ [available] s’ String.P(A) String.P(A) String.P(A) 2 1 3 3 3 5 4 [unavailable] [unavailable] noticket s 4 s1 s2 s3

(39)

Double accept Address Date s reject s T s d s A B A B A B A B A

Arequests session s with B

Asends type Tto B

Acan choose to repeat this part of the session Aselects dat B Aand Bclose s 3c 3d P(A) = !{ ticket: !<Double>. ?{ accept: ?(Address).!<Date>, reject: }, noticket: } Customer Subagent (A|B|T)

Session s’ s’ Session s’ occurs between A and B [o] s’ If o then Session s’ occurs

between A and B

[o] s’ If o then Arequests session s with B A B 3b 3b 3a Figure 4.7: Legend

We will now have an outbranchstatement in the protocol, after Agency re-ceives the order from the Customer. Through it the Agency will inform the Customer whether or not it can provide a service. The Agency knows that this will be done by the Subagents but as far as the Customer is concerned, the only session he has to know about is the one with Agency.

(40)

final noalias protocol p_ac {//Agency to customer sbegin. ?(String) .!{ TICKET: !<Double>. ?{//Nested branching ACCEPT: ?(Address).!<Date>, REJECT: }, NOTICKET: } }

(AC) Agency - Customer Protocol

final noalias protocol p

{//delegated protocol !{ TICKET: !<Double> .?{ ACCEPT: ?(Address).!<Date>, REJECT: }, NOTICKET: } }

final noalias protocol p_sa

{ //subagent - agency

sbegin.?(@(p)).?(String) }

final noalias protocol p_ab

{//subagent a to subagent b

cbegin.

!<@(p)>.!<String> }

(SP) Subagent Protocols

In listing (AC) the Agency is the party who decide whether the ticket can or cannot be provided, and hence have theoutbranchstatement around the options TICKET, providing a ticket and

NOTICKET, unable to provide a ticket.

This will correspond to the outbranch statement while the customer will be implemented by aninbranchstatement. Something new in this variation is that we have nested branch loops, and it’d be interesting to see if SJ can cope with this. In listing (SP), the delegated protocol p has been changed to reflect the changes to the Agency - Customer scenario but the principle is the same, the Subagent receives the remaining protocol and if necessary, delegates it further down the chain.

4.4.4

Implementation

An easy mistake to make (or that I made) in the initial attempt to program a Subagent, might be to try and follow the protocol step by step as:

if (getAvailability(travDetails)) {

s_sc.outbranch(TICKET){....// follow protocol as listing below};

}

else

{

s_sc.outbranch(NOTICKET){...//session with Customer ends};

(41)

However we must remember that the Customer is only informed that no ticket is available ifnoneof the Subagents can provide a ticket. Whereas theifstatement part of the code above is correct, theelsestatement is only correct in the case of the very last Subagent in the chain of delegation.

Hence, for the rest of the Subagents the implementation would be: if(getAvailability(travDetails)) { s_sc.outbranch(TICKET) { ... s_sc.send(cost); s_sc.inbranch() { case ACCEPT: {

storeInDatabase((Address) s_sc.receive()); ....

s_sc.send(date); }

case REJECT: { System.out.println("Price Rejected"); } }

} }

else { ... //delegate }

with the delegation part inside the else statement being almost identical to the one in (SA).

Due to the curly brackets around each inbranch case and inside theoutbranch statements there is no ambiguity to the programmer of what the above code would mean. As I later found out, there were no problems in compiling or running the program either. SJ dealt with nested branching without any pecu-liarities.

Other than it’s respective change in protocol, no change in the implementation of Agency was required. The implementation of customer is has to be altered to match the new protocol.

...

s_ca.send(trav_method);

s_ca.inbranch() {

case TICKET:

{... // follow protocol }

case NOTICKET:

{... // session ends here }

}

These changes in implementation are straightforward. By changing the protocol we know that there have to be changes made to both parties involved in it. As an example, for every

!{...}

added to the protocol, we must add anoutbranchstatement to the party imple-menting it, in this case Agency. And for everyoutbranchstatement in Agency,

References

Related documents

 Net working capital means the difference between current assets and current liabilities, and therefore, represents that position of current assets which the firm has to finance

Agreeing to use a particular forum means waiving certain legal rights. In a permissive agreement, the parties waive their objections to litigating in a particular court.

In the present study, deep tube well water samples were collected from different villages of Patripal Panchayat, Remuna Tehsil, Balasore, District, Odisha,

Questions inquired about how important music was to them during practice, how often they listened to music during different situations in sport and exercise (warm-up,

After they believed, the Lord began to teach them “that they might understand the scriptures, and said unto them, Thus it is written, and thus it behoved Christ to suffer, and to

Furthermore, a recent study has shown that in addition to compressing time spent on site, housing developers in the UK have reported significant reductions in building defects

This is a mechanical part which when pressed makes the current to flow through it. If the switch is released the current stops flowing through it. This helps to control a

It is retained by the Church in the paschal services because everything about the night of Pascha recalls the Sacrament of Baptism: the language and general terminology of