Jon:

here is the code of two programs that you should save (watch for
line-breaks).

The first program should be named "server.rex", the second
"useServer.rex". Invoke as

    rexx useServer.rex [nrClients [useReplyInClientToo]]
    ... nrClients: if not given defaults to '1'
    ...useReplyInClientToo: if  set to '1' (true), then the client
    method 'requestCommand' won't wait for the completion of the request
    but return using reply, adding additional Rexx threads of execution

If you have questions, then please ask. It should be fairly "easy" to
adapt the server code to your SQL-needs and using one instance of a
server from all parts of your ooDialog programs.

Regards

---rony

server-rexx-program:

------------------------------- "server.rex" (begin) 
-------------------------------------
-- rgf, 2010-05-31, demonstrate a server that does its work on a separate thread



/* **************************************************************************** 
*/
::class server public

::method init
  expose busy requests stop nrOfProcessedRequests
  busy=.false
  requests=.queue~new
  stop=.false
  nrOfProcessedRequests=0

::attribute stop     -- if set to .true, then "doTheWork" will stop working
::attribute busy     -- indicates worker is busyly working
::attribute requests -- queue of command objects
::attribute nrOfProcessedRequests   -- accumulator counting nr of processed 
requests

::method string
  expose busy
  return self~objectName"@"self~identityHash"@TID:"getTId()"/busy="pp(busy)

::method startToWork unguarded   -- worker method, runs on its own thred
  expose busy requests stop nrOfProcessedRequests
  say self", doTheWork() starting out on thread:" getTID()  -- show TID this 
runs
  reply              -- return to caller, start a new thread

  say self", doTheWork(), after reply now running on thread:" getTID()  -- show 
TID this runs
  self~setup         -- e.g. create a database connection
  do forever
     say self": waiting for requests or stop ..."
     guard on when requests~items>0 | stop=.true
     say self": now running again, requests or stop occurred..."
     if stop=.true then
     do
        say self": stop occurred, shutting down server..."
        leave
     end
     busy=.true

     do while requests~items>0            -- process all pending requests
         workItem=requests~pull           -- pull workItem object
         self~processWorkItem(workItem)   -- do whatever work has to be done
         nrOfProcessedRequests+=1         -- increment counter
     end
     busy=.false
     guard off
  end
  self~shutdown      -- e.g. release a database connection

::method stopToWork  -- cause the worker method to stop
  expose stop
  stop=.true


::method setup       -- setup whatever the worker needs
  say self": in method setup() ..."

::method shutdown    -- shutdown whatever the worker has initiated
  say self": in method shutdown() ..."

::method processWorkItem
  use arg workItem

  say self": in method processWorkItem(), workItem="pp(workItem) "..."
  workItem~completed=.true -- indicate that work has completed on this workItem



/* **************************************************************************** 
*/
::class WorkItem public
::method init
  expose  commandName arguments completed
  use arg commandName, arguments
  completed=.false

::attribute commandName -- any command the server understands
::attribute arguments   -- any arguments to be processed in the command
::attribute completed   -- indicate whether processing has completed

::method string
  expose commandName arguments completed
  return 
self~objectName":commandName="commandName",arguments="arguments",completed="completed


/* **************************************************************************** 
*/
::routine getTID public -- works only under Windows
 if SysVersion()~left(1)="W" then
    return SysQueryProcess("TID")
 return "TID:n/a"

::routine pp public     -- enclose string value in square brackets
  parse arg val
  return "["val"]"
------------------------------- "server.rex" (end) 
---------------------------------------



client-rexx-program:

------------------------------- "useServer.rex" (begin) 
-------------------------------------
-- rgf, 2010-05-31, demonstrate using a server that does its work on a separate 
thread

parse arg maxClients useReply
if maxClients=""|\datatype(maxClients,"W") then
   maxClients=1            -- default to one client

useReply=(useReply=.true)

parse source s
say "client-program:" s"/TID:"getTID()
say "client-program: using REPLY on the client object's 
'requestCommand'-method?" pp(useReply)
say "--- client-program: creating and starting server..."
server=.server~new         -- create one server
server~startToWork

say "--- client-program: creating" pp(maxClients) "clients using the server..."
clientArray=.array~new
do i=1 to maxClients
   o=.client~new(server, useReply)  -- create a client, supply server to use
   clientArray~append(o)   -- save it in the array
   say o
   o~requestCommand("sleep", "i-"random()) -- send a command
end

sleepTime=1
say "--- client-program: sleeping" sleepTime "sec"
call sysSleep sleepTime
say "--- client-program: after sleeping all client's requests should be 
processed ..."

do o over clientArray
   say o
end
say
say "--- client-program: stopping server..."
server~stopToWork
say "--- client-program: finished."


::requires server.rex

::class client public   -- each client works on its own thread

::method init
  expose server useReply
  use arg server, useReply

::attribute server         -- our single server

::method string
  expose server
  return 
self~objectName"@"self~identityHash"@TID:"getTId()"/server~nrOfProcessedRequests="pp(server~nrOfProcessedRequests)

::method requestCommand    -- request a service from the server
  expose server useReply

  if useReply then
     reply                 -- we could also add multithreading here

  use arg command, arguments
  workItem=.WorkItem~new(command,arguments)

  server~requests~queue(workItem)
  -- say "workItem="pp(workItem) "requests in queue:" pp(server~requests~items)
  say self": just added" pp(workItem)", now requests in queue:" 
pp(server~requests~items)
------------------------------- "useServer.rex" (end) 
---------------------------------------




------------------------------------------------------------------------------

_______________________________________________
Oorexx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to