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]