def runpf_consumer_loop(<EOL>in_queue_url,<EOL>workdir,<EOL>lc_altexts=('<STR_LIT>',),<EOL>wait_time_seconds=<NUM_LIT:5>,<EOL>shutdown_check_timer_seconds=<NUM_LIT>,<EOL>sqs_client=None,<EOL>s3_client=None<EOL>):
if not sqs_client:<EOL><INDENT>sqs_client = boto3.client('<STR_LIT>')<EOL><DEDENT>if not s3_client:<EOL><INDENT>s3_client = boto3.client('<STR_LIT>')<EOL><DEDENT>signal.signal(signal.SIGINT, kill_handler)<EOL>signal.signal(signal.SIGTERM, kill_handler)<EOL>shutdown_last_time = time.monotonic()<EOL>while True:<EOL><INDENT>curr_time = time.monotonic()<EOL>if (curr_time - shutdown_last_time) > shutdown_check_timer_seconds:<EOL><INDENT>shutdown_check = shutdown_check_handler()<EOL>if shutdown_check:<EOL><INDENT>LOGWARNING('<STR_LIT>')<EOL>break<EOL><DEDENT>shutdown_last_time = time.monotonic()<EOL><DEDENT>try:<EOL><INDENT>work = awsutils.sqs_get_item(in_queue_url,<EOL>client=sqs_client,<EOL>raiseonfail=True)<EOL>if work is not None and len(work) > <NUM_LIT:0>:<EOL><INDENT>recv = work[<NUM_LIT:0>]<EOL>action = recv['<STR_LIT>']['<STR_LIT:action>']<EOL>if action != '<STR_LIT>':<EOL><INDENT>continue<EOL><DEDENT>target = recv['<STR_LIT>']['<STR_LIT:target>']<EOL>args = recv['<STR_LIT>']['<STR_LIT:args>']<EOL>kwargs = recv['<STR_LIT>']['<STR_LIT>']<EOL>outbucket = recv['<STR_LIT>']['<STR_LIT>']<EOL>if '<STR_LIT>' in recv['<STR_LIT>']:<EOL><INDENT>out_queue_url = recv['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>out_queue_url = None<EOL><DEDENT>receipt = recv['<STR_LIT>']<EOL>try:<EOL><INDENT>lc_filename = awsutils.s3_get_url(<EOL>target,<EOL>altexts=lc_altexts,<EOL>client=s3_client<EOL>)<EOL>runpf_args = (lc_filename, args[<NUM_LIT:0>])<EOL>pfresult = runpf(<EOL>*runpf_args,<EOL>**kwargs<EOL>)<EOL>if pfresult and os.path.exists(pfresult):<EOL><INDENT>LOGINFO('<STR_LIT>' %<EOL>(lc_filename, pfresult))<EOL>resp = s3_client.list_objects_v2(<EOL>Bucket=outbucket,<EOL>MaxKeys=<NUM_LIT:1>,<EOL>Prefix=pfresult<EOL>)<EOL>outbucket_list = resp.get('<STR_LIT>',[])<EOL>if outbucket_list and len(outbucket_list) > <NUM_LIT:0>:<EOL><INDENT>LOGWARNING(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% target<EOL>)<EOL>awsutils.sqs_delete_item(in_queue_url, receipt)<EOL>continue<EOL><DEDENT>put_url = awsutils.s3_put_file(pfresult,<EOL>outbucket,<EOL>client=s3_client)<EOL>if put_url is not None:<EOL><INDENT>LOGINFO('<STR_LIT>' % put_url)<EOL>if out_queue_url is not None:<EOL><INDENT>awsutils.sqs_put_item(<EOL>out_queue_url,<EOL>{'<STR_LIT>':put_url,<EOL>'<STR_LIT:target>': target,<EOL>'<STR_LIT>':lc_filename,<EOL>'<STR_LIT>':kwargs},<EOL>raiseonfail=True<EOL>)<EOL><DEDENT>os.remove(pfresult)<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>' % pfresult)<EOL>os.remove(pfresult)<EOL><DEDENT>awsutils.sqs_delete_item(in_queue_url, receipt)<EOL>if ( (lc_filename is not None) and<EOL>(os.path.exists(lc_filename)) ):<EOL><INDENT>os.remove(lc_filename)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>LOGWARNING('<STR_LIT>' %<EOL>(lc_filename,))<EOL>with open('<STR_LIT>' %<EOL>lc_filename, '<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(<EOL>{'<STR_LIT>':in_queue_url,<EOL>'<STR_LIT:target>':target,<EOL>'<STR_LIT>':lc_filename,<EOL>'<STR_LIT>':kwargs,<EOL>'<STR_LIT>':outbucket,<EOL>'<STR_LIT>':out_queue_url},<EOL>outfd, pickle.HIGHEST_PROTOCOL<EOL>)<EOL><DEDENT>put_url = awsutils.s3_put_file(<EOL>'<STR_LIT>' % lc_filename,<EOL>outbucket,<EOL>client=s3_client<EOL>)<EOL>if out_queue_url is not None:<EOL><INDENT>awsutils.sqs_put_item(<EOL>out_queue_url,<EOL>{'<STR_LIT>':put_url,<EOL>'<STR_LIT>':lc_filename,<EOL>'<STR_LIT>':kwargs},<EOL>raiseonfail=True<EOL>)<EOL><DEDENT>awsutils.sqs_delete_item(in_queue_url,<EOL>receipt,<EOL>raiseonfail=True)<EOL>if ( (lc_filename is not None) and<EOL>(os.path.exists(lc_filename)) ):<EOL><INDENT>os.remove(lc_filename)<EOL><DEDENT><DEDENT><DEDENT>except ClientError as e:<EOL><INDENT>LOGWARNING('<STR_LIT>')<EOL>break<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>')<EOL>if '<STR_LIT>' in locals():<EOL><INDENT>with open('<STR_LIT>' %<EOL>lc_filename,'<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(<EOL>{'<STR_LIT>':in_queue_url,<EOL>'<STR_LIT:target>':target,<EOL>'<STR_LIT>':lc_filename,<EOL>'<STR_LIT>':kwargs,<EOL>'<STR_LIT>':outbucket,<EOL>'<STR_LIT>':out_queue_url},<EOL>outfd, pickle.HIGHEST_PROTOCOL<EOL>)<EOL><DEDENT>put_url = awsutils.s3_put_file(<EOL>'<STR_LIT>' % lc_filename,<EOL>outbucket,<EOL>client=s3_client<EOL>)<EOL>if out_queue_url is not None:<EOL><INDENT>awsutils.sqs_put_item(<EOL>out_queue_url,<EOL>{'<STR_LIT>':put_url,<EOL>'<STR_LIT>':lc_filename,<EOL>'<STR_LIT>':kwargs},<EOL>raiseonfail=True<EOL>)<EOL><DEDENT>if ( (lc_filename is not None) and<EOL>(os.path.exists(lc_filename)) ):<EOL><INDENT>os.remove(lc_filename)<EOL><DEDENT><DEDENT>awsutils.sqs_delete_item(in_queue_url,<EOL>receipt,<EOL>raiseonfail=True)<EOL><DEDENT><DEDENT><DEDENT>except KeyboardInterrupt:<EOL><INDENT>LOGWARNING('<STR_LIT>')<EOL>break<EOL><DEDENT>except ClientError as e:<EOL><INDENT>LOGWARNING('<STR_LIT>')<EOL>break<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>')<EOL>if '<STR_LIT>' in locals():<EOL><INDENT>with open('<STR_LIT>' %<EOL>lc_filename,'<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(<EOL>{'<STR_LIT>':in_queue_url,<EOL>'<STR_LIT:target>':target,<EOL>'<STR_LIT>':kwargs,<EOL>'<STR_LIT>':outbucket,<EOL>'<STR_LIT>':out_queue_url},<EOL>outfd, pickle.HIGHEST_PROTOCOL<EOL>)<EOL><DEDENT>put_url = awsutils.s3_put_file(<EOL>'<STR_LIT>' % lc_filename,<EOL>outbucket,<EOL>client=s3_client<EOL>)<EOL>if out_queue_url is not None:<EOL><INDENT>awsutils.sqs_put_item(<EOL>out_queue_url,<EOL>{'<STR_LIT>':put_url,<EOL>'<STR_LIT>':kwargs},<EOL>raiseonfail=True<EOL>)<EOL><DEDENT>if ( (lc_filename is not None) and<EOL>(os.path.exists(lc_filename)) ):<EOL><INDENT>os.remove(lc_filename)<EOL><DEDENT><DEDENT>awsutils.sqs_delete_item(in_queue_url, receipt, raiseonfail=True)<EOL><DEDENT><DEDENT>
This runs period-finding in a loop until interrupted.

    Consumes work task items from an input queue set up by `runpf_producer_loop`
    above.

    Parameters
    ----------

    in_queue_url : str
        The SQS URL of the input queue to listen to for work assignment
        messages. The task orders will include the input and output S3 bucket
        names, as well as the URL of the output queue to where this function
        will report its work-complete or work-failed status.

    workdir : str
        The directory on the local machine where this worker loop will download
        the input light curves, process them, and produce its output
        periodfinding result pickles. These will then be uploaded to the
        specified S3 output bucket, and then deleted from the local disk.

    lc_altexts : sequence of str
        If not None, this is a sequence of alternate extensions to try for the
        input light curve file other than the one provided in the input task
        order. For example, to get anything that's an .sqlite where .sqlite.gz
        is expected, use altexts=[''] to strip the .gz.

    wait_time_seconds : int
        The amount of time to wait in the input SQS queue for an input task
        order. If this timeout expires and no task has been received, this
        function goes back to the top of the work loop.

    shutdown_check_timer_seconds : float
        The amount of time to wait before checking for a pending EC2 shutdown
        message for the instance this worker loop is operating on. If a shutdown
        is noticed, the worker loop is cancelled in preparation for instance
        shutdown.

    sqs_client : boto3.Client or None
        If None, this function will instantiate a new `boto3.Client` object to
        use in its SQS operations. Alternatively, pass in an existing
        `boto3.Client` instance to re-use it here.

    s3_client : boto3.Client or None
        If None, this function will instantiate a new `boto3.Client` object to
        use in its S3 operations. Alternatively, pass in an existing
        `boto3.Client` instance to re-use it here.

    Returns
    -------

    Nothing.