IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 10, 2008, 12:51:04 PM (18 years ago)
Author:
eugene
Message:

allow job stdout / stderr from pclient to arrive slowly

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/pcontrol/GetJobOutput.c

    r16472 r20047  
    11# include "pcontrol.h"
    2 # define PCLIENT_TIMEOUT 500
     2# define PCLIENT_TIMEOUT 100
     3# define DEBUG 0
    34
    4 /* we read Nbytes from the host, then watch for the prompt */
    5 int GetJobOutput (char *cmd, Host *host, IOBuffer *buffer, int Nbytes) {
     5// we are trying to read a total of Nbytes from the host.  This function may be called
     6// repeatedly until the buffer has the complete set of data.  We need to read output[0].size
     7// bytes, then look for the PCLIENT_PROMPT in the output stream
     8
     9int GetJobOutput (char *command, Host *host, JobOutput *output) {
    610 
    7   int i, status, Nstart;
    811  char *line;
     12  int i, status;
    913  struct timespec request, remain;
    1014
    11   ASSERT (cmd, "cmd missing");
     15  ASSERT (command, "command missing");
    1216  ASSERT (host, "host missing");
    13   ASSERT (buffer, "buffer missing");
     17  ASSERT (output, "output missing");
    1418
    15   /* flush any earlier messages */
    16   ReadtoIOBuffer (buffer, host[0].stdout_fd);
    17   FlushIOBuffer (buffer);
    18   Nstart = buffer[0].Nbuffer;
    19 
    20   /* avoid blocking on waitpid, test every 100 usec, up to 50 msec */
     19  /* avoid blocking on waitpid, test every 100 usec, up to 10 msec */
    2120  request.tv_sec = 0;
    2221  request.tv_nsec = 100000;
    2322
    24   /* send cmd (stdout / stderr) */
    25   status = write_fmt (host[0].stdin_fd, "%s\n", cmd);
     23  if (!output[0].requested) {
     24      /* send command (stdout / stderr) */
     25      status = write_fmt (host[0].stdin_fd, "%s\n", command);
    2626
    27   /* is pipe still open? */
    28   if ((status == -1) && (errno == EPIPE)) return (PCLIENT_DOWN);
     27      /* is pipe still open? */
     28      if ((status == -1) && (errno == EPIPE)) return PCLIENT_DOWN;
     29      output[0].requested = TRUE;
     30  }
    2931
    30   /* read at least Nbytes, then watch for PCLIENT_PROMPT */
     32  if (output[0].completed) return PCLIENT_GOOD;
     33
     34  // attempt to read the output->size bytes from the host
     35  if (output[0].buffer.Nbuffer < output[0].size) {
     36      status = -1;
     37      for (i = 0; (i < PCLIENT_TIMEOUT) && (status != 0) && (output[0].buffer.Nbuffer < output[0].size); i++) {
     38          status = ReadtoIOBuffer (&output[0].buffer, host[0].stdout_fd);
     39          if (status == -1) nanosleep (&request, &remain);
     40      }
     41      if (VerboseMode()) gprint (GP_ERR, "%s\n Read %d of %d bytes so far\n", output[0].buffer.buffer, output[0].buffer.Nbuffer, output[0].size);
     42      if (status == 0) {
     43          if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
     44          return PCLIENT_DOWN;
     45      }
     46      if (output[0].buffer.Nbuffer < output[0].size) {
     47          if (VerboseMode()) gprint (GP_ERR, "host %s still has data, keep trying\n", host[0].hostname);
     48          return PCLIENT_HUNG;
     49      }
     50  }
     51
     52  // keep trying to read until we get the prompt
    3153  line = NULL;
    3254  status = -1;
    3355  for (i = 0; (i < PCLIENT_TIMEOUT) && (status != 0) && (line == NULL); i++) {
    34     status = ReadtoIOBuffer (buffer, host[0].stdout_fd);
    35     if ((buffer[0].Nbuffer - Nstart) >= Nbytes) {
    36       line = memstr (buffer[0].buffer, PCLIENT_PROMPT, buffer[0].Nbuffer);
    37     }
     56    status = ReadtoIOBuffer (&output[0].buffer, host[0].stdout_fd);
     57    line = memstr (output[0].buffer.buffer, PCLIENT_PROMPT, output[0].buffer.Nbuffer);
    3858    if (status == -1) nanosleep (&request, &remain);
    3959  }
    40   if (status ==  0) return (PCLIENT_DOWN);
    41   if (status == -1) return (PCLIENT_HUNG);
    42 
    43   /* check on success of pclient command */
    44   switch (status) {
    45     case -1:
    46       if (VerboseMode()) gprint (GP_ERR, "host %s is not responding\n", host[0].hostname);
    47       return (FALSE);
    48 
    49     case 0:
    50       if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    51       return (FALSE);
    52 
    53     default:
    54       if (VerboseMode()) gprint (GP_ERR, "message received (GetJobOutput : %s)\n", cmd); 
    55       /* drop extra bytes from pclient (not pclient:job) */
    56       buffer[0].Nbuffer = Nstart + Nbytes;
    57       if (buffer[0].Nalloc > buffer[0].Nbuffer) {
    58         bzero (buffer[0].buffer + buffer[0].Nbuffer, buffer[0].Nalloc - buffer[0].Nbuffer);
    59       }
    60       return (TRUE);
     60  if (VerboseMode()) gprint (GP_ERR, "%s\n Read %d of %d bytes so far\n", output[0].buffer.buffer, output[0].buffer.Nbuffer, output[0].size);
     61  if (status == 0) {
     62    if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
     63    return PCLIENT_DOWN;
     64  }
     65  if (line == NULL) {
     66    if (VerboseMode()) gprint (GP_ERR, "host %s not yet at prompt, keep trying\n", host[0].hostname);
     67    return PCLIENT_HUNG;
    6168  }
    6269
    63   gprint (GP_ERR, "programming error: should not reach here (GetJobOutput)\n");
    64   pcontrol_exit (50);
     70  output[0].completed = TRUE;
     71  return PCLIENT_GOOD;
    6572}
Note: See TracChangeset for help on using the changeset viewer.