5 GlobalStore Demo examples

In this chapter we'll present some concrete applications which use some functionality provided by this package.

5.1 Faut-tolerant Collaborative drawing application

The application example is a multi-user drawing application. Each user have its own drawing area. A user draws rectangles on the drawing area and moves them with the mouse. The abstraction maintains the coherence of all user's display. The following original centralised program uses the QTk Module. It shows how graphics objects can be controlled on a canvas. We can create rectangles, click on them and drag them with the mouse.

Source File

functor 
import 
   QTk
export 
define 
  Canvas
  Desc=td(canvas( handle:Canvas
                  glue:nswe
                  bg:white))                  
   Window={QTk.build Desc}    
   ListColors= [red green blue yellow]
   Colors={NewCell ListColors}
   proc{CreateRectangle X Y}
     Tag
     Col
   in 
      Tag={Canvas newTag($)}
      case {Access Colors $} of 
         Color|then Col=Color  
      [] nil then {Assign Colors ListColors} Col=red
      end    
      {Assign Colors {List.drop {Access Colors $} 1 $}}
      {Canvas create(rectangle X-50 Y-50 X+50 Y+50 fill:Col tags:Tag)}
      {Bindevent Tag}                
   end 
   proc {Bindevent Tag}      
      {Tag bind(event:"<B1-ButtonRelease>" 
                args:[int(x) int(y)]
                action:proc{$ X Y}
                          {Tag setCoords(X-50 Y-50 X+50 Y+50)}
                       end)}
   end 
   {Canvas bind(event:"<2>" 
                args:[int(x) int(y) ]
               action:CreateRectangle)}  
in   
 {Window show(wait:true)}
end 

To make the drawing program a fault tolerant distributed application, the original centralised program is modified in the following way: First, we create a new global store.

Source File

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a new global store
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
functor 
import 
   OS
   Open
   GlobalStore(newStore:NewStore)  
   Application
   Connection
   Pickle
   System(show:Show)
define 
   Pid F
   Ls
   %%% Store emulator pid in a file : user by the test failure script  
   try 
      Pid={OS.getPID}
      F={New Open.file init(name:'/tmp/pidserver' flags:[write create])}       
      {F write(vs:Pid)}
      {F close}
   catch 
      error(_)
   then 
      {Show 'ErrorCreateFile'}
   end    
    
   try 
      {NewStore ?Ls}
      % pickle LS and offer it to clients
      {Pickle.save {Connection.offerUnlimited Ls $} './gsticket'}
   catch 
      gs(failed_globalstore_creation) then 
      {Show errorNewStore }{Application.exit 0}       
   [] error(url(_ _) debug:_) then {Show 'cannot create url or file '}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end 
end 

Second, we modify the original centralised code by connecting the new user to the global store and using transactions when we update rectangle objects.

Source File

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Example illustrating the GS
%% Author Ilies Alouini
%% Last Modification 9-9-2000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
functor 
import  
   System(show:Show)
   Module
   Pickle
   Connection
   Application
export 
define 
   %%% rectangle object class in the Global Store
   class Rectangle 
      prop locking
      attr 
         ox:0
         oy:0
         order
         color
      meth init(X Y Order Color)
         ox <- X
         oy <- Y
         order <- Order
         color <- Color
      end 
      meth getcoord(X Y)
         lock 
            X=@ox
            Y=@oy
         end 
      end 
      meth setcoord(X Y)
         lock 
            ox <- X  
            oy <- Y  
         end 
      end 
      meth getorder(O)
         O=@order
      end 
      meth getcolor(Col)
         Col=@color
      end 
   end 
    
   [QTk]={Module.link ["./QTk.ozf"]}   
   Canvas
   Desc=td(canvas(
                  handle:Canvas
                  glue:nswe
                  bg:white))
                  %tdscrollbar:true
                  %lrscrollbar:true))    
   Window={QTk.build Desc}    
    
   %%%%%%% Dictionary of pairs order store object, store object#graphic object
   Dictobjects={NewDictionary $}
   NewObj LocalStore  Movehere LS
   ListColors= [red green blue yellow]
   Colors={NewCell ListColors}
   proc{UpdateRectangle X Y Obj ?Tag}        
      Tag={Canvas newTag($)}  
      {Canvas create(rectangle X-50 Y-50 X+50 Y+50 fill:{Obj getcolor($)} tags:Tag)}
      {Bindevent Tag Obj}      
   end 
   proc{CreateRectangle X Y}
      Order Sobj       
      Tag
      Col
   in 
      Tag={Canvas newTag($)}
      case {Access Colors $} of 
         Color|then Col=Color  
      [] nil then {Assign Colors ListColors} Col=red
      end 
      {Assign Colors {List.drop {Access Colors $} 1 $}}   
      try          
         Sobj={NewObj  Rectangle init(X Y  Order Col)}
         {Canvas create(rectangle X-50 Y-50 X+50 Y+50 fill:Col tags:Tag)}
         {LocalStore getuniqueident(?Order)}      
         {Dictionary.put Dictobjects Order Sobj#Tag}
         {Bindevent Tag Sobj}          
   catch gs(global_store_temporary_failed) then 
      {Show 'Object not created: retry'}
   end 
   end   
   proc {Bindevent Tag  Sobj}      
      {Tag bind(event:"<B1-ButtonRelease>" 
                args:[int(x) int(y)]
                action:proc{$ X Y}
                          Out Transid
                          proc {Trans Output}
                            {Sobj setcoord(X Y)}
                          end 
                       in 
                          %{Canvas canvasx(OX ?X)}
                          %{Canvas canvasy(OY ?Y)}  
                          {Tag setCoords(X-50 Y-50 X+50 Y+50)}
                          % initialise transaction on Tag
                          {LocalStore trans(Trans Out Transid)}
                          %{LocalStore checktrans(Transid Res _)}                   
                       end)}
   end 
   {Canvas bind(event:"<2>" 
                args:[int(x) int(y) ]
                action:CreateRectangle)}
 
   
   RedrawAll
in 
   %%%%%%%%%%%%%%%%%%%%%%%%%
   %% Initiate a local store
   %%%%%%%%%%%%%%%%%%%%%%%%%   
   try LS={Connection.take {Pickle.load './gsticket' $}}
   catch 
    error(url(_ _) debug:_) then {Show 'url or file not found'}
   [] error(connection(_ _)  debug:_)  then {Show connectionfailed}
   end 
    
   try 
      {LS newLocal(Module user1  ?NewObj ?LocalStore ?Movehere)}
   catch gs(connectionfailed)
   then 
      {Show connectionfailed}
   end 
   try {Pickle.save {Connection.offerUnlimited LocalStore $} './client1ticket'}
   catch 
    error(url(_ _) debug:_) then {Show 'cannot create url or file '}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end 
   %%% Save the MOvehere procedure
   try {Pickle.save {Connection.offerUnlimited Movehere $} './movehereticket'}
   catch 
    error(url(_ _) debug:_) then {Show 'cannot create url or file '}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end  
   % set action when object creation
   {LocalStore setnotifycreation(
      proc {$ O}
         Tag X Y Ord in 
         {O getorder(Ord)}
         {Wait Ord}
         {O getcoord(X Y)}
         {UpdateRectangle X Y O ?Tag}
         {Dictionary.put  Dictobjects Ord  O#Tag}
      end)}
   %%%% Redraw All Objects
   proc {RedrawAll}
       Entries En  in 
       % sort Graphic objects
      {Dictionary.keys Dictobjects ?Entries}
      {List.sort Entries Value.'<' ?En}  
       % redraw all objects in order
       {ForAll En
        proc {$ Order}
           O  X Y Tag   Go in 
           {Dictionary.get Dictobjects Order  O#Go}
           {Go delete}    
           {O getcoord(X Y)}
           {UpdateRectangle X Y O ?Tag}
           {Dictionary.remove Dictobjects Order}
           {Dictionary.put Dictobjects Order O#Tag}
        end 
       }
    end 
   % set action when receiving Obj object update
   {LocalStore setnotifyupdate(
    proc {$ ?Obj}
      {RedrawAll}
    end)
   }
   {LocalStore setnotifyabort(
     proc {$ ?Obj}
        {RedrawAll}
     end 
    )
   }  
 {Window show(wait:true)}
end 

We can now create another new user connected to GS:

Source File

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Example illustrating the GS
%% Author Ilies Alouini
%% Last Modification 9-9-2000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
functor 
import  
   System(show:Show)
   Module
   Application
   Connection
   Pickle
export 
define 
   %%% rectangle object class in the Global Store
   class Rectangle 
      prop locking
      attr 
         ox:0
         oy:0
         order
         color
      meth init(X Y Order Color)
         ox <- X
         oy <- Y
         order <- Order
         color <- Color
      end 
      meth getcoord(X Y)
         lock 
            X=@ox
            Y=@oy
         end 
      end 
      meth setcoord(X Y)
         lock 
            ox <- X  
            oy <- Y  
         end 
      end 
      meth getorder(O)
         O=@order
      end 
      meth getcolor(Col)
         Col=@color
      end 
   end 
    
   [QTk]={Module.link ["./QTk.ozf"]}   
   Canvas
   Desc=td(canvas(
                  handle:Canvas
                  glue:nswe
                  bg:white))
                  %tdscrollbar:true
                  %lrscrollbar:true))    
   Window={QTk.build Desc}    
    
   %%%%%%% Dictionary of pairs order store object, store object#graphic object
   Dictobjects={NewDictionary $}
   NewObj LocalStore LS Movehere
   ListColors= [red green blue yellow]
   Colors={NewCell ListColors}
   proc{UpdateRectangle X Y Obj ?Tag}        
      Tag={Canvas newTag($)}  
      {Canvas create(rectangle X-50 Y-50 X+50 Y+50 fill:{Obj getcolor($)} tags:Tag)}
      {Bindevent Tag Obj}      
   end 
   proc{CreateRectangle X Y}
      Order Sobj       
      Tag
      Col
   in 
      Tag={Canvas newTag($)}
      case {Access Colors $} of 
         Color|then Col=Color  
      [] nil then {Assign Colors ListColors} Col=red
      end    
      {Assign Colors {List.drop {Access Colors $} 1 $}}
      try 
         Sobj={NewObj  Rectangle init(X Y  Order Col)}
         {Canvas create(rectangle X-50 Y-50 X+50 Y+50 fill:Col tags:Tag)}
         {LocalStore getuniqueident(?Order)}      
         {Dictionary.put Dictobjects Order Sobj#Tag}
         {Bindevent Tag Sobj}
   catch gs(global_store_temporary_failed) then 
      {Show 'Object not created: retry'}
   end               
   end   
   proc {Bindevent Tag  Sobj}      
      {Tag bind(event:"<B1-ButtonRelease>" 
                args:[int(x) int(y)]
                action:proc{$ X Y}
                          Out Transid
                          proc {Trans Output}
                            {Sobj setcoord(X Y)}
                          end 
                       in 
                          {Tag setCoords(X-50 Y-50 X+50 Y+50)}
                          % initialise transaction on Tag
                          {LocalStore trans(Trans Out Transid)}
                          %{LocalStore checktrans(Transid Res _)}                   
                       end)}
   end 
   {Canvas bind(event:"<2>" 
                args:[int(x) int(y) ]
               action:CreateRectangle)}
    
  RedrawAll
in 
   %%%%%%%%%%%%%%%%%%%%%%%%%
   %% Initiate a local store
   %%%%%%%%%%%%%%%%%%%%%%%%%
     
   try LS={Connection.take {Pickle.load './client1ticket' $}}
   catch 
    error(url(_ _) debug:_) then {Show 'url or file not found'}
   [] error(connection(_ _)  debug:_)  then {Show connectionfailed}
   end    
    
   try 
      {LS newlocal(Module user1  ?NewObj?LocalStore ?Movehere)}
   catch gs(connectionfailed)
   then 
      {Show connectionfailed}
   end 
    
   
  % set action when object creation
   {LocalStore setnotifycreation(
      proc {$ O}
         Tag X Y Ord in 
         {O getorder(Ord)}
         {Wait Ord}
         {O getcoord(X Y)}
         {UpdateRectangle X Y O ?Tag}
         {Dictionary.put  Dictobjects Ord  O#Tag}
      end)}
   %%%% Redraw All Objects
   proc {RedrawAll}
       Entries En  in 
       % sort Graphic objects
       {Dictionary.keys Dictobjects ?Entries}
      {List.sort Entries Value.'<' ?En}
      
       % redraw all objects in order
       {ForAll En
        proc {$ Order}
           O  X Y Tag   Go in 
           {Dictionary.get Dictobjects Order  O#Go}
           {Go delete}
           {O getcoord(X Y)}
           {Go delete}
           {UpdateRectangle X Y O ?Tag}
           {Dictionary.remove Dictobjects Order}
           {Dictionary.put Dictobjects Order O#Tag}
        end 
       }
    end 
    % set action when receiving Obj object update
   {LocalStore setnotifyupdate(
    proc {$ ?Obj}
      {RedrawAll}
    end)
   }
   {LocalStore setnotifyabort(
     proc {$ ?Obj}
        {RedrawAll}
     end 
    )
   }
   {Window show(wait:true)}
end 

5.2 Fine grained transactions

This example illustrates the use of fine grained transactions to update object counters (see comments in the source code). First, we must create a new global store as it is described in the previous section. Then, we create two users connected to GS.

First user Program:

Source File

functor 
import 
   System(show:Show)
   OS
   Open
   Pickle
   Connection
   Module
define 
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %%% Store emulator pid in a file
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   F Pid
   try 
      Pid={OS.getPID}
      F={New Open.file init(name:'/tmp/pidclient'#Pid flags:[write create])}       
      {F write(vs:Pid)}
      {F close}
   catch 
   error(_)
   then 
   {Show 'ErrorCreateFile'}
   end 
   %%%%%%%%%%%%%%%%%%%%%%%%%
   %% Connect to GS
   %%%%%%%%%%%%%%%%%%%%%%%%%   
   LS
   try LS={Connection.take {Pickle.load './gsticket' $}}
   catch 
    error(url(_ _) debug:_) then {Show 'url or file not found'}
   [] error(connection(_ _)  debug:_)  then {Show connectionfailed}
   end 
   NewObj LocalStore Movehere
   try 
      {LS newLocal(Module user1  ?NewObj ?LocalStore ?Movehere)}
   catch gs(connectionfailed)
   then 
      {Show connectionfailed}
   end 
   try {Pickle.save {Connection.offerUnlimited LocalStore $} './client1ticket'}
   catch 
    error(url(_ _) debug:_) then {Show 'cannot create url or file '}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end 
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Create objects in the store:
   %  Obj1 Obj2 Obj3 are references in
   %  the LocalStore  
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
   class Counter 
      attr val
      meth show(Value) Value=@val end 
      meth inc(Value)
         val <- @val+Value
         %{Obj3 dec(1)}
      end 
      meth dec(Value)
         val <- @val-Value  
      end 
      meth init(Value) val <- Value end   
   end 
    
   Obj1={NewObj  Counter init(0)}
   Obj2={NewObj  Counter  init(0)}
   Obj3={NewObj  Counter  init(0)}
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Save  Obj1 reference to use it on other clients
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   try {LocalStore saveobj(Obj1 '/usr/staff/ila/=Oz/store/o1globalref')}
   catch 
      gs(use_localstore_localreference) then {Show 'cannot apply methods on remote clients'}
   [] error(url(_ _) debug:_) then {Show 'cannot create url or file '}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end 
     
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Procedure to show a coherent
   % snapshot of the global store
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   proc {CoherentSnapshot}
      C={NewCell 0}      
      proc{Trans Output}
         Val1 Val2 Val3 in 
         {Obj1 show(Val1)}  
         {Obj2 show(Val2)}
         {Obj3 show(Val3)}
         Output=state(Val1 Val2 Val3)
      end 
      Trid
      Out
      Res
    in 
     % State of objects Obj1 Obj2 is coherent here
     % show  state of  objects in a file after 1mn of period
      if {OS.time  $} - {Access C $}>=20
      then 
         %Localstore may raise the  exception:
         %   gs(use_localstore_localreference)
         %   gs(undefinedmethod#Meth)
         %   gs(invalidcall) % for waitlocks, retrans, newthread, {O M}
         {LocalStore trans(Trans Out ?Trid)}  % raise gs(ill_formed_transaction)
         {LocalStore checktrans(Trid Res _)}                  
         if Res==commit  then 
            {Show 'Obj1:'#Out.1#'Obj2:'#Out.2#'Obj3:'#Out.3}
         else 
            skip 
         end          
         {Assign C {OS.time  $}}
      else 
         skip 
      end 
   end    
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Initialise transactions
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   LastTransid
   fun {Iterate I}
      Transid  Retransid        
      proc{Trans Out}
         proc {Iteratebis J}          
            if J\=0
            then 
               %{LocalStore waitlocks([Obj1 Obj2])}   
               {Obj1 inc(1)}
               {Obj1 inc(~1)}
               %{LocalStore newthread(proc {$} {Show 'newthread'} {Obj1 inc(1)} end)}
               %if {IsEven {Obj1 show($)}}==true
                %  then  
                  {Obj2 inc(~1)}        
                  {Obj2 inc(2)}
              % else
                %  skip
               %end                   
               {Obj1 inc(1)}
               {Obj1 inc(~1)}
               {Obj1 inc(1)}
               {Obj1 inc(~1)}
               {Obj1 inc(1)}
               %{LocalStore waitlocks([Obj3 Obj1])}  
               {Obj3 inc(1)}
               {Iteratebis J-1}
            else 
               skip 
            end 
         end 
         OutPut
      in 
          
         {Iteratebis 1}
        %  {LocalStore retrans(
%              proc {$ Out}
%                 {Obj1 inc(1)}
%                {Obj3 inc(1)}          
%              end
%                OutPut
%             ?Retransid)
%          }
      end 
      Out
   in 
      if I\=0
      then     
         {LocalStore trans(Trans Out ?Transid)}
         %{Delay 1}
         if I==then 
           LastTransid=Transid  
           %LastTransid=Retransid
         else 
            skip 
           end 
         (Transid#Transid)|{Iterate I-1}
         %(Transid#Retransid)|{Iterate I-1}
      else 
         nil
      end 
   end 
    
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Migrate the global store
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %thread
   %   {Delay 15000}
   %   {Movehere Module _ proc{$} skip end }
   %end
    
   Transset={Iterate 2000}
   
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Wait for the end of transactions and updates  
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %{Wait {LocalStore checktrans(LastTransid $ _)}}     % For transactions  
   {Wait {LocalStore termination($)}} % For updates
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Compute number of committed/aborted transactions
   %% Compute number of committed/aborted retransactions
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   Ccommit={NewCell 0} Cabort={NewCell 0}
   Crcommit={NewCell 0} Crabort={NewCell 0}
   Crecompute={NewCell 0} Crrecompute={NewCell 0}
   {ForAll Transset  
    proc{$ Pair}
       Tr RTr Res Resb Nb Nbr in 
       if Pair\=nil then 
          Pair=Tr#RTr
          {LocalStore checktrans(Tr ?Res ?Nb)}
           
          {Assign Crecompute  {Access Crecompute  $}+Nb}   
          if  Res==commit
          then 
             {Assign Ccommit {Access Ccommit  $}+1}
          else 
             {Assign Cabort {Access Cabort $}+1}
          end 
          if {Access Ccommit  $}+{Access Cabort  $}==2000 then 
             {Show 'Number of local committed transaction:'#{Access Ccommit  $}}
             {Show 'Number of local aborted transaction:'#{Access Cabort  $}}
             {Show 'Number of local recomputed transaction:'#{Access Crecompute  $}}
          else 
             skip 
          end 
          if {IsFree RTr} then 
             Resb=abort % Thread terminated before executing retrans
             Nbr=0
          else 
             {LocalStore checktrans(RTr Resb Nbr)}
          end 
          {Assign Crrecompute  {Access Crrecompute  $}+Nbr}  
          if Resb==commit
          then 
             {Assign Crcommit {Access Crcommit  $}+1}
          else 
             {Assign Crabort {Access Crabort $}+1}
          end 
          if {Access Crcommit  $}+{Access Crabort  $}==2000 then 
             {Show 'Number of local aborted retrans:'#{Access Crabort  $}}
             {Show 'Number of local committed retrans :'#{Access Crcommit  $}}
             {Show 'Number of local recomputed retrans:'#{Access Crrecompute  $}}
          else 
             skip 
          end 
           
       else 
          skip 
       end 
    end 
   }   
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Show states of objects
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   
   {CoherentSnapshot}
       
end 

Second user Program:

Source File

functor 
import 
   System(show:Show)     
   OS
   Open
   Connection
   Pickle
   Module
   Application
define  
   class Counter 
      attr val
      meth show(Value) Value=@val end 
      meth inc(Value) val <- @val+Value end 
      meth init(Value) val <- Value end   
   end 
   %%% Store emulator pid in a file
   F Pid  
   try 
      Pid={OS.getPID}
      F={New Open.file init(name:'/tmp/pidclient'#Pid flags:[write create])}       
      {F write(vs:Pid)}
      {F close}
   catch 
      error(_)
   then 
   {Show 'ErrorCreateFile'}
   end    
   %%% deamon to simulate site failure
   %{OS.system "deamon" _}
   %%%
   %%%%%%%%%%%%%%%%%%%%%%%%%
   %% Initiate a local store
   %%%%%%%%%%%%%%%%%%%%%%%%%
    LS
   try LS={Connection.take {Pickle.load './client1ticket' $}}
   catch 
    error(url(_ _) debug:_) then {Show 'url or file not found'}
   [] error(connection(_ _)  debug:_)  then {Show connectionfailed}
   end    
   LocalStore NewObjInStore Movehere
   try 
      {LS newLocal(Module user1  ?NewObjInStore ?LocalStore ?Movehere)}
   catch gs(connectionfailed)
   then 
      {Show connectionfailed}
   end 
   {Delay 15000}
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Create an object in the store
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   Obj1 Obj2 Obj3  
   Obj3={NewObjInStore  Counter init(0)}
   Obj2={NewObjInStore  Counter init(0)}
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %%% Get the local reference of an object
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   try 
      {LocalStore getobj('/usr/staff/ila/=Oz/store/o1globalref' ?Obj1)}
    
   catch 
      gs(objectlost) then {Show 'object lost'}
   []  error(url(_ _) debug:_) then {Show 'url or file not found'}
   [] error(connection(_ _)  debug:_)  then {Show 'connection Module error'}
   end    
    
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Procedure to show a coherent
   % snapshot of the global store
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   CoherentSnapshot
   proc {CoherentSnapshot}
      C={NewCell 0}
      proc{Trans Output}
         Val1 Val2 Val3 in 
         {Obj1 show(Val1)}  
         {Obj2 show(Val2)}
         {Obj3 show(Val3)}
         Output=state(Val1 Val2 Val3)
      end 
      Trid
      Out
      Res
    in 
     % State of objects Obj1 Obj2 is coherent here
     % show  state of  objects in a file after 1mn of period
      if {OS.time  $} - {Access C $}>=20
      then 
         {LocalStore trans(Trans Out ?Trid)}
         {LocalStore checktrans(Trid Res _)}                  
         if Res==commit  then 
               {Show 'Obj1:'#Out.1#'Obj2:'#Out.2#'Obj3:'#Out.3}
         else 
            skip 
         end             
         {Assign C {OS.time  $}}
      else 
         skip 
      end 
   end    
   %%%%%%%%%%%%%%%%%%%
   % Init transactions  
   %%%%%%%%%%%%%%%%%%%
   Transset Iterate  
   fun  {Iterate I}
      Transid Iteratebis Retransid        
      proc{Trans Out}
         proc  {Iteratebis J}
            if J\=0
            then  
               {Obj1 inc(1) }
               {Obj2 inc(~1)}
               {Iteratebis J-1}                  
            else 
               skip 
            end 
         end 
      in 
         %{LocalStore waitlocks([Obj1 Obj3])}  
         %{LocalStore newthread(proc {$} {Show 'newthread'} {Obj1 inc(1)} end)}    
         {Iteratebis 1}
         {Obj1 inc(1) }
         {Obj1 inc(~1) }
         {Obj1 inc(1) }
         {Obj1 inc(~1) }
         {Obj1 inc(1) }
         {Obj3 inc(1) }  
      end 
     Out  
   in 
      if I\=0
      then 
         {LocalStore trans(Trans Out Transid)}
         {Delay 60}
         Transid#Transid|{Iterate I-1}
      else 
         nil
      end  
   end 
   Transset={Iterate 1000}    
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% Compute number of committed/aborted transactions
   %% Wait for the end of transactions and updates ..
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   {Wait {LocalStore termination($)}} %   
   Ccommit={NewCell 0} Cabort={NewCell 0} Crcommit={NewCell 0}
   Crabort={NewCell 0}  
   Crecompute={NewCell 0} Crrecompute={NewCell 0}
   {ForAll Transset  
    proc{$ Pair}
       Tr RTr Res Resb Nb Nbr in 
       if Pair\=nil then 
          Pair=Tr#RTr
          {LocalStore checktrans(Tr Res Nb)}
          {Assign Crecompute  {Access Crecompute  $}+Nb}   
          if  Res==commit
          then 
             {Assign Ccommit {Access Ccommit  $}+1}
          else 
             {Assign Cabort {Access Cabort $}+1}
          end 
          if {Access Ccommit  $}+{Access Cabort  $}==1000 then 
             {Show 'Number of local committed transaction:'#{Access Ccommit  $}}
             {Show 'Number of local aborted transaction:'#{Access Cabort  $}}
             {Show 'Number of local recomputed transaction:'#{Access Crecompute  $}}
          else 
             skip 
          end 
          {LocalStore checktrans(RTr Resb Nbr)}
          {Assign Crrecompute  {Access Crrecompute  $}+Nbr}  
          if Resb==commit
          then 
             {Assign Crcommit {Access Crcommit  $}+1}
          else 
             {Assign Crabort {Access Crabort $}+1}
             end 
          if {Access Crcommit  $}+{Access Crabort  $}==1000 then 
             {Show 'Number of local aborted retrans :'#{Access Crabort  $}}
             {Show 'Number of local committed retrans :'#{Access Crcommit  $}}
             {Show 'Number of local recomputed retrans:'#{Access Crrecompute  $}}
          else 
             skip 
          end 
           
       else 
          skip 
       end 
    end 
   }    
   {CoherentSnapshot}
end 
         

5.3 Mobile agent application

NOT YET COMPLETED


Ilies Alouini
Version 1.1.1 (20000902)