JSPM

  • Created
  • Published
  • Downloads 322
  • Score
    100M100P100Q100724F
  • License MIT

Mutex Server using WebSocket

Package Exports

  • mutex-server

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (mutex-server) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Mutex Server

1. Outline

GitHub license npm version Downloads Build Status

Critical sections in the network level.

The mutex-server is an npm module that can be used for building a mutex server. When you need to control a critical section on the entire system level, like distributed processing system using the network communications, this mutex-server can be a good solution.

Opens a mutex-server and let clients to connect to the mutex-server. When sharing network level critical sections through the mutex-server, you don't need to worry about any accident like sudden network disconnection by power outage. If a client has been disconnected by accident, all of the locks had been acquired by the client would be automatically released.

2. Features

2.1. Network

2.2. Components

2.3. Dependencies

3. Usage

3.1. Server

Building a mutex server is very simple like below:

import { MutexServer } from "mutex-server";

async function main(): Promise<void>
{
    let server: MutexServer<string, null> = new MutexServer();
    await server.open(44114, async acceptor => 
    {
        if (acceptor.header === "qweqwe123!")
            await acceptor.accept(null);
        else
            await acceptor.reject();
    });
}

3.2. Client

Using the mutex server is also easy too. However, be careful when using the remote mutex. If you forget unlocking the remote mutex, other clients would be suffered by your mistake.

import { MutexConnector, RemoteMutex } from "mutex-server";

async function main(): Promise<void>
{
    // CONNECT TO THE SERVER
    let connector: MutexConnector<string, null> = new MutexConnector("qweqwe123!", null);
    await connector.connect("http://127.0.0.1:44114");

    //----
    // USE MUTEX
    //----
    // GET NAMED MUTEX
    let mutex: RemoteMutex = connector.getMutex("someName");

    // WRITE-LOCK
    await mutex.lock();
    {
        // ...
        // DO SOMETHING
        // ...
    }
    await mutex.unlock();

    // READ-LOCK
    await mutex.lock_shared();
    {
        // ...
        // DOM SOMETHING
        // ...
    }
    await mutex.unlock_shared();

    await connector.close();
}

3.3. Learn from Example

import ms from "mutex-server";
import std from "tstl";

const PASSWORD = "qweqwe123!";
const PORT = 37119;

async function client(character: string): Promise<void>
{
    // CONNECT TO THE SERVER
    let connector: ms.MutexConnector<string, null> = new ms.MutexConnector(PASSWORD, null);
    await connector.connect(`ws://127.0.0.1:${PORT}`);
    
    // GET LOCK
    let mutex: ms.RemoteMutex = await connector.getMutex("printer");
    await mutex.lock();

    // PRINTS A LINE VERY SLOWLY MONOPOLYING THE MUTEX
    for (let i: number = 0; i < 20; ++i)
    {
        process.stdout.write(character);
        await std.sleep_for(50);
    }
    process.stdout.write("\n");

    // RANDOM UNLOCK
    if (Math.random() < 0.5)
        await mutex.unlock();

    // ALTHOUGH THE CLIENT DOES NOT RELEASE THE LOCK
    // SERVER WILL UNLOCK IT AUTOMATICALLY AFTER THE DISCONNECTION
    await connector.close();
}

async function main(): Promise<void>
{
    // OPEN SERVER
    let server: ms.MutexServer<string, null> = new ms.MutexServer();
    await server.open(PORT, async acceptor =>
    {
        if (acceptor.header === PASSWORD)
            await acceptor.accept(null);
        else
            await acceptor.reject();
    });

    // CREATE 10 CLIENTS LOCKING MUTEX
    let promises: Promise<void>[] = [];
    for (let i: number = 0; i < 4; ++i)
    {
        let character: string = std.randint(0, 9).toString();
        promises.push( client(character) );
    }

    // WAIT THE CLIENTS TO BE DISCONNCTED AND CLOSE SERVER
    await Promise.all(promises);
    await server.close();
}
main();

4. Appendix

4.1. Repositories

4.2. Documents

4.3. Dependencies

4.3.1. TypeScript

4.3.2. TSTL

4.3.3. TGrid