Size: 4693
Comment:
|
← Revision 9 as of 2018-03-03 11:39:17 ⇥
Size: 145
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
~-<<SeeSaw(section="table-of-contents", show="true", seesaw="false", toshow="<<(Show>> table-of-contents)", tohide="<<(Hide>> table-of-contents)", speed="Slow")>>-~ <<TableOfContents>> `ServiceState` is part of the CategoryAplTree project. == Overview == {{{ServiceState}}} is a class that offers an interface between the Windows SCM (Service Control Manager) and a Dyalog APL application running as a service. In you application workspace you need to have a function on `⎕LX` like this: {{{ Start [1] #.WinFile.PolishCurrentDir [2] rideFlag←0 [3] timeout←3 [4] #.myServiceState←⎕NEW #.ServiceState rideFlag timeout [5] '#'⎕WS'Event' #.myServiceState.Event_QuitDQ 1 [6] :If myServiceState.IsRunningAsService [7] {}myServiceState.EstablishServiceCallback ⍬ ⍝ This does not work! [8] {#.TestService.Run ⍵}&⍬ [9] ⎕DQ'.' [10] #.TestService.Off [11] :Else [12] #.TestService.Run ⍬ [13] :EndIf }}} Note that this example focuses just on getting the application running as a service. Remarks: '''[1]''': This makes sure that if the workspace carries a path the work (or current) directory is set accordingly. '''[2]''': Flags that indicates whether the service is expected to connect to Ride or not. '''[3]''': Timeout: this defines how long the `ServiceState` class will wait for the application to conform a requested state change. '''[4]''': This instantiates the `ServiceState` class. '''[5]''': `#.myServiceState.Event_QuitDQ` is a variable carrying an (any) integer. The application is supposed to send the same integer to `#` (when it wants to stop) in order to quit the `⎕DQ` on line 9. '''[6]''': Checks whether the application is actually running as a Windows Service. '''[7]''': This establishes `#.ServiceState.EstablishServiceCallback` as a callback that will handle all messages send by the Windows SCM. Well, it should. At the time of writing an instance methods that is associated with an event cause a NONCE ERROR, so we must circumvent thus Dyalog bug for the time being with something like this: {{{ '.'⎕WS'Event' 'ServiceNotification' '#.OnServiceHandler' }}} The `#.OnServiceHandler` function in turn calls the instance method: {{{ OnServiceHandler←{ #.myServiceState.OnServiceHandler ⍵ } }}} That works. '''[8]''': Here we start the real application. Note that this '''must''' run in its own thread because otherwise the application might well become unresponsive. '''[9]''': We need to execute `⎕DQ '.'` in order to make sure that the interpreter processes all events. '''[10]''': At this stage we need to execute `⎕OFF`; that's what `#.TestService.Off` is doing. == The application == The application must make sure that it checks whether a state change was requested. This can be done by calling certain helpers as shown in this example: {{{ MainLoop dummmy;buffer;data;event;obj;rc;r;msg;cs [1] Log 'Server got started' [2] :While 1 [3] ⎕DL 1 [4] :If #.myServiceState.ShallServicePause [5] {}#.myServiceState.ConfirmStateChange ⍬ [6] Log'The service is pausing' [7] {}#.myServiceState.WaitForContinue ⍬ [9] {}#.myServiceState.ConfirmStateChange ⍬ [10] Log'The service is no longer pausing' [11] :EndIf [12] :If #.myServiceState.ShallServiceQuit [13] {}#.myServiceState.ConfirmStateChange ⍬ [14] Log'The service is in the process of shutting down...' [15] :Leave [16] :EndIf [17] :EndWhile [18] ⎕NQ'#'#.ServiceState.Events.QuitDQ }}} Remarks: '''[14]''': This makes sure that the `⎕DQ` in `Start[7]` quits. Apart from `ShallServicePause` and `ShallServiceQuit` there is also a function `ShallServiceContinue` but this is called by this function: {{{ {r}←WaitForContinue dummy [1] ⍝ Returns always ⍬. [2] ⍝ Consider calling this in case ShallServicePause has returned a 1 and you don't _ [3] ⍝ have to do any particular gymnastics but just want to wait for a state change. [4] ⍝ It just waits until the status changes, although not necessarily to "continue". [5] r←⍬ [6] :While 0=ShallServiceContinue [7] ⎕DL 1 [8] :EndWhile }}} == Project Page == For bug reports, future enhancements and a full version history see [[ServiceState/ProjectPage]] == Version Information == ||Original author: ||KaiJaeger || ||Responsible: ||KaiJaeger || ||Email: || kai@aplteam.com || <<Include(APLTreeDownloads)>> ---- CategoryAplTree [[CategoryAPLTreeProject]] |
The project has been relocated to [[https://github.com/aplteam/ServiceState]] on 2018-03-03. |
ServiceState: interface between SCM and APL
The project has been relocated to https://github.com/aplteam/ServiceState on 2018-03-03.