Assignment 2 of soen423

                       Assignment 2 of soen423

First Try

1. General analysis

Here is a simple example of how UDP sockets work in java.

2. How should I implement "dualBid"?

a) This is a transaction which means either all or none. That is to say, you have to guarantee that either both of bids are

placed or none of them are placed. A simple 2-phase-transaction protocol is used here.

b) The following is the pseudo code for this function.

boolean dualBid(...)

{

    boolean result=false;

    if (checkFirstBid(...))

    {

        //here we need to put some protection mechanism to guarantee the first item won't change status.

        //how to implement it? (See below problem A)

        if (UDPSendBidRequest(...))

        {

            //here we must be pretty sure this operation ALWAYS succeed. Otherwise rollback is really a pain and

            //also beyond this course. So, question: what can things go wrong? (See below problem B)

            updateFirstItem(...);

            result=true;//only here we succeed!

        }

    }

    return result;

}

 

3. What can make things go wrong?

Problem A: What if I check first item and it is ok, but some other request modified first item and when my UDPSendBidRequest() function returns successfully I cannot update first item? i.e. Another request "placeBid" for first item with a even higher bid. Then when you finished updating bidding of second item, you find out that you have to rollback.

A intuitive approach is to first modify first item and send request to see if we can modify second item. Believe me, this will create more operations than simply "protect first item without modifying it" because usually we assume that modifying a data structure costs more than "protect it". i.e. A data structure exists in database.

So, the most simplest solution is to make "dualBid" to be "synchronized".

Problem B: If I properly protected first item and then send request for second item, is it possible that I might fail to update first item?

In our case it is possible. For example, each item has a "timetoClose". What if the server of auction manager of our second item is very busy and when the request is finally returned successfully, our first item is expired with timetoclose? Then we might need to rollback the bidding in second item. What a mess!

In this assignment, we want to prevent this from happening. So, the simplest solution is setup a fixed "successful-return-deadline" for the request to second item. Say, if the second item can only return success when the first item has only 5 seconds to expire, then we consider this "dualbid" can never be successful. So, we return false.

4. How should I implement a UDP listening module?

You must realize that we need to explicitly create a thread answering request for second item of "dualBid".

class UDPServer extends Thread

{

    public void run()

    {   

        boolean result;

        do

        {

            if (MyUDPReceivedMessage())

        {

            result=processingBidRequest();//What is special about this function? It must also be "synchronized"!!            //because this function will try to modify an item in the same time with other "placeBid' operations.

                replyRequest(result);

            }

        }while (true);

    }

}

Of course you have to start this thread at your DAM at some place.

5. Question: Should we make our "UDP" communication multi-threaded? i.e. For each "dualbid" request, we generate a new thread to handle that.

Answer: Ideally it should be. But it is very complicated in the sense of synchronization and the benefit may not be big because we usually assume this kind of operation or transaction is slow and few.

6. Question: How could we access second interface item when we also define interface of dam?

module auctionDistri {
	interface item {
		attribute string itemNo;
		attribute float currentBid;
		attribute long bidderId;
		attribute long expectedClosingTime;
		//Modify state of item
		void normalize ( in long no, out string n);
		void placeBID(in long bidderId, in long proposedBid, out string res); 
	};
	typedef sequence <item> listOfItems; 
	interface dam {
		void starAuction (in float startBid, out string itemN,in long timeToClose);
		listOfItems listItems ();
		void getBid (in string itemNo, out string bid);
		void placeBid (out string res, in string itemNo,in long bidderId,in long proposedBid);
		void dualBid(out string result, in string bidID, in string itemN1, in long proposedBid1, in string itemN2, in long proposedBid2);  
	};
};

 

Answer: I want to write this down because at beginning I didn't really understand the problem.

...

1. As you already find, the multi-interface won't work. I now recall the similar concept in MS "COM" where we use "querryInterface" from a single base interface "IUnknown" to find all sub-interface. But this support needs implementation. So, it is not trivial to get an interface from another interface unless you "register" both interface in server part. And usually we declare more methods for an interface instead of declaring more interfaces.
 
2. I recall some students in A1 of RMI returns a remote interface instead of returning some concrete data. By invoking the interface returned, he can get the data. This is fancy but inefficient because unless we have special reason, we should not do like this. RPC is expensive and to get one single data, it is not worthwhile to invoke two RPC.
3. For a while, I have the impression that interface cannot be inherited. However, it seems java can. And even c++ also can inherit interface because the implementation class inherits from abstract class which is interface in c++. So, that is origin why I have an illusion that we need to "re-declare implements" which is wrong.
...