PUT /files/util/wait_queue.js HTTP/1.1
Host: 127.0.0.1
Accept-Encoding: identity
Content-Length: 1407
Content-MD5: Zj1Ij/Z1BW/PxKVZBoVpTA==
Expect: 100-continue
Date: Thu, 08 Dec 2016 13:02:40 GMT
User-Agent: aws-cli/1.11.26 Python/2.7.10 Darwin/16.1.0 botocore/1.4.83
Content-Type: application/javascript
Authorization: AWS 123:3Ek/uW/qqIN//zQcvtv3ueqe8xs=

'use strict';

// const _ = require('lodash');
const P = require('../util/promise');
const LinkedList = require('./linked_list');

class WaitQueue {

    constructor(name) {
        name = name || '';
        this._name = '_wq_' + name;
        this._q = new LinkedList(name);
    }

    /**
     * wait in queue, returns a promise which will be resolved on wakeup.
     * item is optional, and if provided can later be passed to wakeup for
     * a manual wakup (not by queue order).
     */
    wait(item) {
        item = item || {};
        const defer = P.defer();
        item[this._name] = defer;
        this._q.push_back(item);
        return defer.promise;
    }

    /**
     * wakeup the item or first item in queue if item is not supplied.
     * returns the item.
     */
    wakeup(item) {
        item = item || this._q.get_front();
        if (!item) {
            return;
        }
        this._q.remove(item);
        item[this._name].resolve();
        delete item[this._name];
        return item;
    }

    /**
     * read-only queue length property
     */
    get length() {
        return this._q.length;
    }

    /**
     * peeks the next item in queue
     */
    head() {
        return this._q.get_front();
    }

    /**
     * @return waiting items enumerated as string
     */
    enum_items() {
        return this._q.enum_items();
    }

}

module.exports = WaitQueue;
