Last active
September 21, 2021 22:41
-
-
Save Perlence/52eb4640f7f02111318430638410b162 to your computer and use it in GitHub Desktop.
Straight-forward thread pool implementation in Racket
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket/base | |
(require racket/match | |
racket/async-channel | |
net/http-client) | |
(define urls '(["icanhazip.com" "/"] | |
["icanhazepoch.com" "/"] | |
["example.com" "/"])) | |
(define (main) | |
(define p (new-pool 4)) | |
(displayln "Sending thunks") | |
(for ([url urls]) | |
(match-let ([(list host path) url]) | |
(pool-put p (λ () | |
(match-let-values ([(status _ port) (http-sendrecv host path)]) | |
(displayln status) | |
(port-count-chars port)))))) | |
(displayln "Reading results") | |
(for ([_ urls]) | |
(displayln (pool-get p))) | |
(pool-close p)) | |
(struct pool (in-ch out-ch threads)) | |
(define (new-pool number-of-threads [out-ch-limit #f]) | |
(define in-ch (make-channel)) | |
(define out-ch (make-async-channel out-ch-limit)) | |
(define threads (for/list ([_ (in-range number-of-threads)]) | |
(thread (λ () | |
(define (get) (channel-get in-ch)) | |
(define (put smth) (async-channel-put out-ch smth)) | |
(let loop ([thunk (get)]) | |
(unless (eq? thunk 'close) | |
(put (thunk)) | |
(loop (get)))))))) | |
(pool in-ch out-ch threads)) | |
(define (pool-put pool thunk) | |
(channel-put (pool-in-ch pool) thunk)) | |
(define (pool-get pool) | |
(async-channel-get (pool-out-ch pool))) | |
(define (pool-close pool) | |
(define in-ch (pool-in-ch pool)) | |
(define threads (pool-threads pool)) | |
(for-each (λ (_) (channel-put in-ch 'close)) threads) | |
(for-each thread-wait threads)) | |
(define (port-count-chars input-port) | |
(define (read) (read-char input-port)) | |
(let loop ([char (read)] | |
[result 0]) | |
(if (eof-object? char) | |
result | |
(loop (read) (add1 result))))) | |
(module+ test | |
(require rackunit) | |
(check-equal? (port-count-chars (open-input-string "abcdefg")) 7)) | |
(module+ main | |
(main)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment