git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

resource_waiter.js (5123B)


      1 /**
      2  * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"). You
      5  * may not use this file except in compliance with the License. A copy of
      6  * the License is located at
      7  *
      8  *     http://aws.amazon.com/apache2.0/
      9  *
     10  * or in the "license" file accompanying this file. This file is
     11  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
     12  * ANY KIND, either express or implied. See the License for the specific
     13  * language governing permissions and limitations under the License.
     14  */
     15 
     16 var AWS = require('./core');
     17 var inherit = AWS.util.inherit;
     18 var jmespath = require('jmespath');
     19 
     20 /**
     21  * @api private
     22  */
     23 function CHECK_ACCEPTORS(resp) {
     24   var waiter = resp.request._waiter;
     25   var acceptors = waiter.config.acceptors;
     26   var acceptorMatched = false;
     27   var state = 'retry';
     28 
     29   acceptors.forEach(function(acceptor) {
     30     if (!acceptorMatched) {
     31       var matcher = waiter.matchers[acceptor.matcher];
     32       if (matcher && matcher(resp, acceptor.expected, acceptor.argument)) {
     33         acceptorMatched = true;
     34         state = acceptor.state;
     35       }
     36     }
     37   });
     38 
     39   if (!acceptorMatched && resp.error) state = 'failure';
     40 
     41   if (state === 'success') {
     42     waiter.setSuccess(resp);
     43   } else {
     44     waiter.setError(resp, state === 'retry');
     45   }
     46 }
     47 
     48 /**
     49  * @api private
     50  */
     51 AWS.ResourceWaiter = inherit({
     52   /**
     53    * Waits for a given state on a service object
     54    * @param service [Service] the service object to wait on
     55    * @param state [String] the state (defined in waiter configuration) to wait
     56    *   for.
     57    * @example Create a waiter for running EC2 instances
     58    *   var ec2 = new AWS.EC2;
     59    *   var waiter = new AWS.ResourceWaiter(ec2, 'instanceRunning');
     60    */
     61   constructor: function constructor(service, state) {
     62     this.service = service;
     63     this.state = state;
     64     this.loadWaiterConfig(this.state);
     65   },
     66 
     67   service: null,
     68 
     69   state: null,
     70 
     71   config: null,
     72 
     73   matchers: {
     74     path: function(resp, expected, argument) {
     75       var result = jmespath.search(resp.data, argument);
     76       return jmespath.strictDeepEqual(result,expected);
     77     },
     78 
     79     pathAll: function(resp, expected, argument) {
     80       var results = jmespath.search(resp.data, argument);
     81       if (!Array.isArray(results)) results = [results];
     82       var numResults = results.length;
     83       if (!numResults) return false;
     84       for (var ind = 0 ; ind < numResults; ind++) {
     85         if (!jmespath.strictDeepEqual(results[ind], expected)) {
     86           return false;
     87         }
     88       }
     89       return true;
     90     },
     91 
     92     pathAny: function(resp, expected, argument) {
     93       var results = jmespath.search(resp.data, argument);
     94       if (!Array.isArray(results)) results = [results];
     95       var numResults = results.length;
     96       for (var ind = 0 ; ind < numResults; ind++) {
     97         if (jmespath.strictDeepEqual(results[ind], expected)) {
     98           return true;
     99         }
    100       }
    101       return false;
    102     },
    103 
    104     status: function(resp, expected) {
    105       var statusCode = resp.httpResponse.statusCode;
    106       return (typeof statusCode === 'number') && (statusCode === expected);
    107     },
    108 
    109     error: function(resp, expected) {
    110       if (typeof expected === 'string' && resp.error) {
    111         return expected === resp.error.code;
    112       }
    113       // if expected is not string, can be boolean indicating presence of error
    114       return expected === !!resp.error;
    115     }
    116   },
    117 
    118   listeners: new AWS.SequentialExecutor().addNamedListeners(function(add) {
    119     add('RETRY_CHECK', 'retry', function(resp) {
    120       var waiter = resp.request._waiter;
    121       if (resp.error && resp.error.code === 'ResourceNotReady') {
    122         resp.error.retryDelay = (waiter.config.delay || 0) * 1000;
    123       }
    124     });
    125 
    126     add('CHECK_OUTPUT', 'extractData', CHECK_ACCEPTORS);
    127 
    128     add('CHECK_ERROR', 'extractError', CHECK_ACCEPTORS);
    129   }),
    130 
    131   /**
    132    * @return [AWS.Request]
    133    */
    134   wait: function wait(params, callback) {
    135     if (typeof params === 'function') {
    136       callback = params; params = undefined;
    137     }
    138 
    139     var request = this.service.makeRequest(this.config.operation, params);
    140     request._waiter = this;
    141     request.response.maxRetries = this.config.maxAttempts;
    142     request.addListeners(this.listeners);
    143 
    144     if (callback) request.send(callback);
    145     return request;
    146   },
    147 
    148   setSuccess: function setSuccess(resp) {
    149     resp.error = null;
    150     resp.data = resp.data || {};
    151     resp.request.removeAllListeners('extractData');
    152   },
    153 
    154   setError: function setError(resp, retryable) {
    155     resp.data = null;
    156     resp.error = AWS.util.error(resp.error || new Error(), {
    157       code: 'ResourceNotReady',
    158       message: 'Resource is not in the state ' + this.state,
    159       retryable: retryable
    160     });
    161   },
    162 
    163   /**
    164    * Loads waiter configuration from API configuration
    165    *
    166    * @api private
    167    */
    168   loadWaiterConfig: function loadWaiterConfig(state) {
    169     if (!this.service.api.waiters[state]) {
    170       throw new AWS.util.error(new Error(), {
    171         code: 'StateNotFoundError',
    172         message: 'State ' + state + ' not found.'
    173       });
    174     }
    175 
    176     this.config = this.service.api.waiters[state];
    177   }
    178 });