yglukhov / asyncthreadpool

Awaitable threadpool for nim
MIT License
48 stars 2 forks source link

asyncthreadpool Build Status

Awaitable threadpool in nim

Differences from built-in threadpool

Usage example

import asyncthreadpool, asyncdispatch
proc myTask(a, b: int): int = a + b
let t = newThreadPool()
let r = waitFor t.spawn myTask(3, 2)
assert(r == 5)

Note: in async functions you should use await instead of waitFor.

Spawning a task without a threadpool

import asyncthreadpool, asyncdispatch
proc myTask(a, b: int): int = a + b
let r = waitFor spawn myTask(2, 3)
assert(r == 5)

Note: in async functions you should use await instead of waitFor.

Thread context usage

Threadpools allow to have thread specific contexts of arbitrary type, specified upon pool creation. These contexts may later be accessed by the tasks. This can be useful in some cases, like a thread-pooled http client that has one socket per thread, and keeps the sockets open in between the tasks (http requests). In the following example there are two tasks: myTask, and getContext. myTask increments the thread-local context, and getContext just returns it's value to the owning thread thread. The tasks can accept the context as a (optionally var) argument. The context is reffered to with a magic keyword threadContext which is awailable only within the spawn statement.

import asyncthreadpool, asyncdispatch
type MyContext = int
proc myTask(a, b: int, ctx: var MyContext): int =
  inc ctx
  a + b
proc getContext(ctx: MyContext): MyContext = ctx
let t = newThreadPool(MyContext, 1) # Create a single-threaded pool
echo waitFor t.spawn myTask(3, 2, threadContext) # Increments thread context
echo waitFor t.spawn myTask(3, 2, threadContext) # Increments thread context
let r = waitFor t.spawn getContext(threadContext)
assert r == 2

Note: in async functions you should use await instead of waitFor.