/**********************************************************************/
/**********************************************************************/
/*  THE FILES CONTAINED HEREIN ARE PROVIDED BY SAS INSTITUTE INC.     */
/*  "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,  */
/*  INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF            */
/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. RECIPIENTS  */
/*  ACKNOWLEDGE AND AGREE THAT SAS INSTITUTE SHALL NOT BE LIABLE      */
/*  WHATSOEVER FOR ANY DAMAGES ARISING OUT OF THEIR USE OF THIS       */
/*  MATERIAL. IN ADDITION, SAS INSTITUTE WILL PROVIDE NO SUPPORT FOR  */
/*  THE MATERIALS CONTAINED HEREIN.                                   */
/**********************************************************************/
/**********************************************************************/


/***********************************************************/
/* Code for the Server                                     */
/***********************************************************/

   /* determine if this session is the server and flag it  */  
tmpdsid=open('server.parmfile');                            
if tmpdsid then do;                                             
   rc=fetch(tmpdsid);                                         
   userid=symget('sysjobid');  /* CMS macro: session id    */
   if userid=getvarc(tmpdsid,varnum(tmpdsid,'serv_id')) 
   then do;   
      server=1;
                                             
         /* CMS: refuse messages--would interrupt server   */
      call execcmdi('cms set msg off'); 
      end;
   else                                                         
      server=0;                                             
      tmpdsid=close(tmpdsid);                                    
   end;                                                           
else                                                            
   server=0;                                                
call symputn('server',server);


   /* 1st time only check stop flag and reset if desired   */  
prepstat: 
   parmdsid=open('server.parmfile','u');                          
   rc=fetch(parmdsid);                 /* check stop flag  */  
   stopflag=getvarn(parmdsid,varnum(parmdsid,'stopflag'));          
   if stopflag=0 then do; /* stop flag is set: reset it?   */  
      call display('system.windows.yesorno.program',                  
         'The Server Stop Flag Is Set',                             
         'Server will immediately shut down if not reset.',     
         'Do you wish to reset the Server stop flag?', 
         '',response);                                                
      if response='1' then do;     /* reset the stop flag  */  
         call putvarn(parmdsid,
                      varnum(parmdsid,'stopflag'),0);        
         rc=update(parmdsid);                                       
      end;                                                           
   end;                                                              
   if parmdsid then parmdsid=close(parmdsid);                       
return;                                                               


chckstat:              /* check and update server status   */
   rc=where(parmdsid); /*important: refreshes file content */  
   rc=fetch(parmdsid);                 /* check stop flag  */  
   stopflag=getvarn(parmdsid,varnum(parmdsid,'stopflag'));          
   maxqueue=getvarn(parmdsid,varnum(parmdsid,'maxqueue'));          
   waitsecs=getvarn(parmdsid,varnum(parmdsid,'waitsecs'));          

      /* if not reasonable wait then default to 10 seconds */
   if waitsecs<5 or waitsecs>60 then 
      waitsecs=10; 
   status=0;                      /* assume status is okay */  
   halt_now=0;                    /* and not halting now   */  
   rc=where(savedsid,'savetime=.');                                 
   if stopflag then do;           /* if stop flag is set   */                         
      if fetch(savedsid)=0 then   /* data left to save     */  
         status=2;            /* status: preparing to halt */  
      else do;
  
            /* no lots to save-make sure none being        */
            /* added and halt                              */  
         status=2;         /* status: preparing to halt    */  
         rc=fetchobs(statusid,1); /* update status file    */  
         call putvarn(statusid,varnum(statusid,'status'),
                               status);     
         call putvarn(statusid,varnum(statusid,'lasttime'),
                               datetime());
         rc=update(statusid);                                       
         _msg_='Server Halting: Waiting 30 seconds to '||  
               ' make sure no new lots being added.';                           
         refresh;                                                     
         currtime=datetime(); 
               /* delay loop                               */                       
            do while (datetime()-currtime < 30);   
            end;                                                         
         rc=where(savedsid,'savetime=.');                           
         if fetch(savedsid)=0 then do;  /* no data added   */  
            status=3;                /* status: shut down  */  
            halt_now=1;              /* halt server now    */
         end;                                                        
         else do; 
               /* status remains at 2: save & try to halt  */  
            _msg_='New lot added. Will save first and '||
               'prepare to halt.';
            refresh;                                                  
            end;                                                        
         end;                                                           
      end;                                /* stop flag set */
   else do;               /* not halting -- too many lots? */  
      if fetchobs(savedsid,maxqueue+1)=0 then   
         status=1;               /* status: too many lots  */                                
   end;                                                               
   rc=rewind(savedsid);                                             

      /* update the status file with new status and time   */  
   rc=fetchobs(statusid,1);                                         
   call putvarn(statusid,varnum(statusid,'status'),status);           
   call putvarn(statusid,varnum(statusid,'lasttime'),
                         datetime());     
   rc=update(statusid);                                             
return;                                                               


server:
   link prepstat;           /* reset stop flag if desired  */  
                                     /* operating params.  */     
   parmdsid=open('server.parmfile','i'); 
                                /* requests: lots to save  */    
   savedsid=open('server.save_req','u'); 
                                /* status and last chk tm  */  
   statusid=open('server.status','u');     
   link chckstat;       /* check and update server status  */  
   do while(not halt_now);  /* repeat until halt flag set  */                                 
                                  /* any data not saved?   */       
      rc=where(savedsid,'savetime=.');
                                /* data needs to be saved  */       
      if fetch(savedsid)=0 then do;

   /* need to determine values so that server can save the */  
   /* data just like a regular session would--get info to  */  
   /* determine which lot to save and create where clause  */
         sku=getvarc(savedsid,varnum(savedsid,'sku'));         
         cntl=getvarc(savedsid,varnum(savedsid,'cntl'));        
         _msg_='SERVER: Saving '||sku||' '||cntl;  
         refresh;
         whrcls="(where=(sku   = '"|| sku   ||"' and "||                 
                        "cntl  = '"|| cntl  ||"'))";  

            /* copy the data into the server's session     */
         rc=copy('server.tmphdr' ||whrcls,'work.tmphdr');                  
         rc=copy('server.tmprslt'||whrcls,'work.tmprslt');
         rc=copy('server.tmpattr'||whrcls,'work.tmpattr');                

            /* open the work files                         */
         hdr_dsid=open('work.tmphdr', 'u');                         
         rsltdsid=open('work.tmprslt','u');                         
         attrdsid=open('work.tmpattr','u');                         

         link savedata;          /* actually do the saving */  
                                 /* close the work files   */
         if hdr_dsid then hdr_dsid=close(hdr_dsid);                 
         if rsltdsid then rsltdsid=close(rsltdsid);                 
         if attrdsid then attrdsid=close(attrdsid);

         rc=delete('work.tmphdr');   /* delete work files  */
         rc=delete('work.tmprslt');                                 
         rc=delete('work.tmpattr');                                 

            /* remove data just saved from server files    */
         do i=1 to 3;
            select(i);                                                
               when(1) filename='server.tmphdr';                              
               when(2) filename='server.tmprslt';                              
               when(3) filename='server.tmpattr';                              
            otherwise;                                             
         end;   /* select                                  */                                       
      tmpdsid=open(filename||whrcls,'u');                     
      do while(fetch(tmpdsid)=0);                               
         rc=delobs(tmpdsid);                                  
      end;                                                      
   if tmpdsid then tmpdsid=close(tmpdsid);                   
      end;                                                         
   end;                                                           
   else do;
 
         /* no lot--delay for few seconds and try again    */  
         /* --avoids putting heavy strain on SAS/SHARE     */  
         /* server--time shows server action on the screen */
      _msg_='Server: Waiting for next lot to save. '||         
                putn(datetime(),'datetime18.');                      
      refresh;                                                     
      currtime=datetime();
                                            /* delay loop  */
      do while (datetime()-currtime < waitsecs);
      end;

         /* to reduce the CPU usage, which can be          */
         /* substantial, some operating systems have a     */
         /* command that can be used instead of this loop  */
         /* to shut down the session for a specified       */
         /* number of seconds--the CMS command is called   */
         /* sleep                                          */
         /*                                                */
         /* call execcmdi ('cms sleep'||                   */
         /*                put(waitsecs,8.0)||'SEC');      */
      end;                                                           
      link chckstat;     /* check and update server status */  
   end;             /* master do loop with stopflag check  */
                                           /* close files  */
   if savedsid then savedsid=close(savedsid);
   if parmdsid then parmdsid=close(parmdsid);                       
   if statusid then statusid=close(statusid);                       
return;