Options
All
  • Public
  • Public/Protected
  • All
Menu

General counting semaphore with Promises.

It allows arbitrary take (also referred to as "P") and free ("V") calls.

To use implementations with the normal JS execution model (single-threaded + queue), take and free are supposed to be called on different 'fibers'. For example, take can be awaited in the business logic processing data while free is called inside a filesystem API callback putting the data into an array.

example

All of the following examples assume a semaphore initialized with a count of 0.

  • take is called 10 times. free is then called once. Exactly one of the previous 10 promises is fulfilled. It is implementation-defined which of them is chosen.
  • free is called 5 times. take is then called 6 times. Exactly 5 of the returned promises get fulfilled "immediately" (for some informal value of immediately).

Hierarchy

  • ISemaphore

Implemented by

Index

Methods

free

  • free(): void
  • Free or 'V' operation.

    If there are any promises returned by {@link take()} still awaiting their fulfillment, exactly of them is fulfilled. The order of fulfillment is implementation-defined.

    Returns void

take

  • take(): Promise<void>
  • Take or 'P' operation.

    Returns Promise<void>

    A promise which is fulfilled when >= 1 of the resource represented by the internal counter is available. This might be the case either if free is called or if the semaphore is initialized with a value > 0.

tryTake

  • tryTake(): boolean
  • Take ('P') if a resource is still available (<=> counter >= 1). Otherwise, do not block (as take does) and return false.

    Returns boolean

    True if a resource could be taken, False otherwise.

tryTakeWithin

  • tryTakeWithin(millis: number): Promise<boolean>
  • Try taking ('P') a resource within the next millis milliseconds.

    example

    Contrary to tryTake, you have to await the promise returned by this method.

    tryTakeWithin(500).then((hasTaken) => ...);
    
    // inside an async function
    const hasTaken = await tryTakeWithin(500);
    
    example

    Instead of simply waiting with take, you can also use this method to regularly give up some computation time, so that other parts of the code can free a resource, while still doing some useful work in case of an unsuccessful attempt.
    Note that this were impossible with take since it does not give up computation time (it is a synchronous method) and the JS VM is single-threaded. Conversely, the other "fibers" must give up their computation power as well (e.g. by yielding or awaiting), this is known as cooperative multitasking.

    // Regularly check for 500ms if we are able to take a resource
    while (!await tryTakeWithin(500)) {
      // If not, do some other work...
    }
    // We finally acquired the resource
    

    Parameters

    • millis: number

    Returns Promise<boolean>

    A promise fulfilling with true if a resource could be taken or false otherwise.

Generated using TypeDoc