-
-
Save smls/bff79cd0b940ffa395261c9126c7ea0b to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/env perl6 | |
# The problem: | |
# - A (pure) function "getinfo" which takes an ID and calculates a | |
# return value based on it. | |
# - Calculating the return value is expensive, so we want to cache | |
# it and never calculate it twice for the same ID. | |
# - The function should be thread-safe, and when called | |
# simultaneously with *different* IDs the calculations should not | |
# block each other. | |
# Implementation: | |
BEGIN ( | |
my $lock = Lock.new; | |
my %info; | |
); | |
sub getinfo ($id) { | |
my $promise; | |
$lock.protect: { | |
$promise = %info{$id} //= start { | |
# expensive calculation here | |
sleep 2; rand | |
} | |
} | |
await $promise | |
} | |
# Testing: | |
await do for 1, 2, 3, 2, 2, 2, 2, 2, 2 { | |
start { say "$_: ", getinfo $_ } | |
} | |
# Output notes: | |
# - The return values for ID 2 are all the same, proving that the | |
# caching works. | |
# - The program only takes 2.x seconds if there are three or more | |
# CPU cores, which proves that the expensive calculations are | |
# done in parallel as they should. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment