3.0.1 • Published 10 months ago

@hazae41/piscine v3.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

piscine

Create async pools with automatic retry

npm i @hazae41/piscine

Node Package 📦

Features

Current features

  • 100% TypeScript and ESM
  • No external dependency
  • Simple API
  • Automatic retry
  • Get a fast random value using Math's PRNG
  • Get a secure random value using WebCrypto's CSPRNG
  • Rust-like resource borrowing and moving

Usage

Create an automatic pool of 10 WebSockets

import "@hazae41/symbol-dispose-polyfill"

import { Box, Deferred, Disposer, Stack } from "@hazae41/box"
import { Future } from "@hazae41/future"
import { test } from "@hazae41/phobos"
import { AutoPool } from "@hazae41/piscine"

async function openOrThrow(socket: WebSocket, signal: AbortSignal) {
  using stack = new Stack()

  const future = new Future<void>()

  const onOpen = () => future.resolve()
  const onError = () => future.reject(new Error("Errored"))
  const onAbort = () => future.reject(new Error("Aborted"))

  socket.addEventListener("open", onOpen, { passive: true })
  stack.push(new Deferred(() => socket.removeEventListener("open", onOpen)))

  socket.addEventListener("error", onError, { passive: true })
  stack.push(new Deferred(() => socket.removeEventListener("error", onError)))

  signal.addEventListener("abort", onAbort, { passive: true })
  stack.push(new Deferred(() => signal.removeEventListener("abort", onAbort)))

  return await future.promise
}

async function createOrThrow(index: number, signal: AbortSignal) {
  const socket = new WebSocket("wss://echo.websocket.org/")
  await openOrThrow(socket, signal)

  const resource = Disposer.wrap(socket, () => socket.close())

  using entry = new Box(resource)
  using stack = new Box(new Stack())

  const onClose = () => pool.delete(index)

  socket.addEventListener("close", onClose, { passive: true })
  stack.get().push(new Deferred(() => socket.removeEventListener("close", onClose)))

  const unentry = entry.unwrapOrThrow()
  const unstack = stack.unwrapOrThrow()

  return Disposer.wrap(unentry, () => unstack[Symbol.dispose]())
}

// Launch a pool of 10 sockets
using pool = new AutoPool<Disposer<WebSocket>>(createOrThrow, 10)

{
  // Borrow socket 0 when it's available
  using borrow = await pool.waitOrThrow(0, x => x?.getOrNull()?.borrowOrNull())
  const socket = borrow.get().get().get()

  socket.send("hello")

  await new Promise(ok => socket.addEventListener("message", ok))

  // Return socket 0 into the pool
}

{
  // Take a random available socket and automatically start creating a new one
  using taken = await pool.waitRandomOrThrow(x => x?.getOrNull()?.unwrapOrNull())
  const socket = taken.get().get()

  socket.send("hello")

  await new Promise(ok => socket.addEventListener("message", ok))

  // Close the socket
}

// Use all stale sockets to send a message
for (const entry of pool) {
  if (entry.isErr())
    continue
  const item = entry.get()

  if (item.borrowed)
    continue
  const socket = item.get().get().get()

  socket.send("hello")
}

// Get all entries
const entries = [...pool]

// Destroy the pool
3.0.1

10 months ago

3.0.0

10 months ago

2.0.3

1 year ago

2.0.2

1 year ago

2.0.5

1 year ago

2.0.4

1 year ago

2.0.1

1 year ago

2.0.0

1 year ago

1.2.16

1 year ago

1.2.14

2 years ago

1.2.15

2 years ago

2.1.2

1 year ago

2.1.1

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.1.0

1 year ago

1.2.12

2 years ago

1.2.11

2 years ago

1.2.8

2 years ago

1.2.7

2 years ago

1.2.6

2 years ago

1.2.10

2 years ago

1.2.9

2 years ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.0

2 years ago

1.2.1

2 years ago

1.1.12-1

2 years ago

1.1.10-3

2 years ago

1.1.12-0

2 years ago

1.1.10-2

2 years ago

1.1.10-1

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.39

3 years ago

1.1.10-7

2 years ago

1.1.9

2 years ago

1.1.8

2 years ago

1.1.10-5

2 years ago

1.1.7

2 years ago

1.1.10-4

2 years ago

1.1.6

2 years ago

1.1.5

2 years ago

1.1.4

2 years ago

1.1.3

2 years ago

1.1.10-8

2 years ago

1.1.2

2 years ago

1.0.40

3 years ago

1.1.12

2 years ago

1.1.11

2 years ago

1.1.10

2 years ago

1.0.42

3 years ago

1.0.41

3 years ago

1.1.16

2 years ago

1.1.15

2 years ago

1.1.14

2 years ago

1.1.13

2 years ago

1.1.19

2 years ago

1.1.18

2 years ago

1.1.17

2 years ago

1.1.23

2 years ago

1.1.22

2 years ago

1.1.20

2 years ago

1.1.25

2 years ago

1.0.19

3 years ago

1.0.18

3 years ago

1.0.17

3 years ago

1.0.38

3 years ago

1.0.16

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.22

3 years ago

1.0.21

3 years ago

1.0.20

3 years ago

1.0.26

3 years ago

1.0.25

3 years ago

1.0.24

3 years ago

1.0.23

3 years ago

1.0.29

3 years ago

1.0.28

3 years ago

1.0.27

3 years ago

1.0.33

3 years ago

1.0.11

3 years ago

1.0.32

3 years ago

1.0.10

3 years ago

1.0.31

3 years ago

1.0.30

3 years ago

1.0.37

3 years ago

1.0.15

3 years ago

1.0.36

3 years ago

1.0.14

3 years ago

1.0.13

3 years ago

1.0.34

3 years ago

1.0.12

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.0

3 years ago