Posted to tcl by Poor Yorick at Wed Feb 09 18:29:11 GMT 2022view pretty
proc waitforstuff {} {
set elapsed [expr {entier(rand() * 2000)}]
after $elapsed [list [info coroutine]]
yield
}
proc worker {spec body args} {
coroutine [info cmdcount] apply [list $spec $body] {*}$args
}
proc collect countvar {
upvar $countvar count
lassign [return -level 0 {*}[
yieldto lindex [list [info coroutine]]]] url
return $url
}
proc done {} {
variable status
puts {Zipped and sent!}
set status 0
}
proc download {dir url callback} {
worker {dir url callback} {
catch {
puts [list downloading $url]
waitforstuff
set content [list content of $url]
if {$url eq {two}} {
error {not two!}
}
save_file $dir $url $content
lindex $url
} cres copts
dict set copts args [list $dir $url]
{*}$callback -options $copts $cres
} $dir $url $callback
}
proc downloads {dir urls} {
set length [llength $urls]
foreach url $urls {
after 0 [
list download $dir $url [list [info coroutine]]]
}
set errors {}
while {[incr length -1] >= 0} {
if {[catch {collect length} cres copts]} {
if {[dict exists $copts args]} {
puts [list error on $dir $url]
}
lappend errors $cres $copts
}
}
return
}
proc save_file {dirvar url content} {
namespace upvar [namespace current] $dirvar dir
puts [list saving to dir $dirvar]
dict set dir $url $content
}
proc zip dirvar {
namespace upvar [namespace current] $dirvar dir
waitforstuff
foreach {key value} $dir {
puts [list $key $value]
}
}
proc mail {} {
puts [list mailed stuff]
}
proc main_coro {argv0 argv} {
yield [list [info coroutine]]
set dir mydir
set urls {one two three}
downloads $dir $urls
zip $dir
mail
done
}
after 0 [coroutine main main_coro $argv0 $argv]