Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | {ycl coro batch} {new package} {ycl coro call} {new package} |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
d24d8665d0111a8f79179ff0ff8bb005 |
| User & Date: | pooryorick 2017-08-04 18:21:54.935 |
Context
|
2017-08-05
| ||
| 20:32 | {ycl coro call} {refactor [reply]} check-in: 59c9a72c4e user: pooryorick tags: trunk | |
|
2017-08-04
| ||
| 18:21 | {ycl coro batch} {new package} {ycl coro call} {new package} check-in: d24d8665d0 user: pooryorick tags: trunk | |
| 18:20 | {ycl coro async} {removed after transfering to {ycl coro call}} check-in: 49d75f7d27 user: pooryorick tags: trunk | |
Changes
Added packages/coro/demo/http_ordertimeout.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#! /bin/env tclsh
package require http
package require {ycl coro relay}
namespace import [yclprefix]::coro::relay
namespace eval doc {}
coroutine geturl apply [list {} {
while 1 {
relay accept {deliver url}
# Because this coroutine uses [yield] directly, [accept] only 1 order
# should be made to it .
coroutine geturl_[info cmdcount] apply [list {deliver url} {
# Synthesize delay for the purpose of the demo
after 5000 [list [info coroutine]]
yield
http::geturl $url -command [info coroutine]
set token [yield]
{*}$deliver [http::data $token]
} [namespace current]] $deliver $url
}
} [namespace current]]
variable doc::main {
description {
Retrieve each URL specified on the command line and print a dictionary
mapping thee URL to its contents .
}
}
coroutine main apply [list {argv0 argv} {
set orders {}
foreach url $argv {
dict set orders [relay order [list 0 1000] geturl $url] $url
}
foreach unused [dict keys [relay pending]] {
set result [relay receive]
lappend results [dict get $orders [relay last]] $result
dict unset orders [relay last]
}
puts $results
# Cancel any outstanding orders
puts [list cancelling orders $orders]
relay cancel orders $orders
exit 0
}] $argv0 $argv
vwait forever
|
Added packages/coro/lib/batch/batch.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#! /bin/env tclsh
package require {ycl coro call}
namespace import [yclprefix]::coro::call::call
namespace import [yclprefix]::coro::call::final
proc add args {
variable task
set id [info cmdcount]
set after [after idle [list after 0] ::coroutine [namespace current]::[
info cmdcount] [namespace current]::runner $id [info coroutine] [
uplevel 1 {namespace current}] $args]
dict set task $id after $after
return $id
}
proc cancel args {
variable task
foreach arg $args {
if {[dict exists $task $arg]} {
after cancel [dict get $task $arg]
dict unset task $arg
}
}
}
proc runner {id caller ns cmd} {
variable task
set res [namespace eval $ns [list [namespace which call] {*}$cmd]]
if {[dict exists $task $id]} {
dict unset task $id
tailcall $caller {*}$res
} else {
# task was canceled in the meantime
}
}
proc wait {} {
return {*}[yieldto return -level 0 [info coroutine]]
}
set task [dict create]
|
Added packages/coro/lib/batch/test.
> > > > > > > | 1 2 3 4 5 6 7 |
#! /bin/env tclsh
package require {ycl coro batch test}
[yclprefix] test main $argv0 $argv {
[yclprefix]::coro::batch::test::suite_main
}
|
Added packages/coro/lib/batch/test.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#! /bin/env tclsh
package require {ycl test}
proc suite_main {} {
package require {ycl list}
namespace import [yclprefix]::list::sl
package require {ycl coro batch}
namespace import [yclprefix]::coro::batch::add
namespace import [yclprefix]::coro::batch::wait
package require {ycl coro call}
namespace import [yclprefix]::coro::call::call
namespace import [yclprefix]::coro::call::reply
namespace import [yclprefix]::coro::call::final
[yclprefix] test init
namespace import [yclprefix]::test::cleanup1
test basic {} -setup {} -body {
variable res
proc c1 value {
coroutine c1_[info cmdcount] ::apply [list value {
reply
after 100 [list [info coroutine]]
reply [expr {$value * $value}]
} [namespace current]] $value
}
coroutine c2 ::apply [list args {
yield [info coroutine]
add [c1 8]
add [c1 5]
lappend res [wait]
lappend res [wait]
set [namespace current]::res $res
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
return $res
} -cleanup [cleanup1] -result [sl {
64 25
}]
cleanupTests
}
|
Added packages/coro/lib/call/call.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#! /bin/env tclsh
proc call {cmd args} {
return {*}[uplevel 1 [list yieldto {*}$cmd [info coroutine] {*}$args]]
}
proc called cmd {
set ns [uplevel 1 {namespace current}]
while 1 {
set orig ${ns}::${cmd}_[info cmdcount]
if {[namespace which $orig] eq {}} {
break
}
}
uplevel 1 [list rename $cmd $orig]
uplevel 1 [list ::apply [list {cmd orig call} {
proc $cmd args [string map [list @orig@ [list $orig] @call@ [list $call]] {
@call@ @orig@ {*}$args
}]
} $ns] $cmd $orig [namespace which call]]
}
proc bye args {
rename [info coroutine] {}
uplevel 1 [list [namespace which reply] -code break {*}$args]
}
proc reply args {
variable callervar
upvar #1 $callervar caller
if {[llength $args]} {
set res [lassign [uplevel 1 [list ::yieldto $caller {*}$args]] caller]
# debug1
if 1 {
if {[string is list $caller] && ![llength $caller] || $caller eq {}} {
return -code error [list {no caller}]
}
}
return $res
} else {
set res [lassign [yieldto return -level 0 [info coroutine]] caller]
return $res
}
}
variable callervar 19IWj=dpgH0PAw^d8i41bwaAVkR73mJiIWgPQm8fOp
|
Added packages/coro/lib/call/test.
> > > > > > > | 1 2 3 4 5 6 7 |
#! /bin/env tclsh
package require {ycl coro call test}
[yclprefix] test main $argv0 $argv {
[yclprefix]::coro::call::test::suite_main
}
|
Added packages/coro/lib/call/test.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
#! /bin/env tclsh
package require {ycl shelf shelf}
namespace import [yclprefix]::shelf::shelf
package require {ycl test}
proc suite_main {} {
package require {ycl list}
namespace import [yclprefix]::list::sl
package require {ycl coro call}
namespace import [yclprefix]::coro::call::call
namespace import [yclprefix]::coro::call::bye
namespace import [yclprefix]::coro::call::reply
namespace import [yclprefix]::coro::call::called
[yclprefix] test init
namespace import [yclprefix]::test::cleanup1
test called {} -setup {} -body {
variable res
coroutine c1 ::apply [list args {
reply
after 1000 [list [info coroutine]]
yield
reply 5
} [namespace current]]
called c1
coroutine c2 ::apply [list args {
variable res
yield
lappend res [c1]
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
return $res
} -cleanup [cleanup1] -result [sl {
5
}]
test basic {} -setup {} -body {
variable res
coroutine c1 ::apply [list args {
reply
after 100 [list [info coroutine]]
yield
set args [reply 5]
} [namespace current]]
coroutine c2 ::apply [list args {
variable res
yield
set res [call c1]
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
return $res
} -cleanup [cleanup1] -result [sl {
5
}]
test break {} -setup {} -body {
variable res
coroutine c1 ::apply [list args {
reply
after 100 [list [info coroutine]]
yield
set args [reply 5]
bye
} [namespace current]]
coroutine c2 ::apply [list args {
yield
variable res
set new {}
while 1 {
lappend new [call c1]
}
lappend res $new
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
lappend res [namespace which c1]
return $res
} -cleanup [cleanup1] -result [sl {
5 {}
}]
test multi {} -setup {} -body {
variable res
coroutine c1 ::apply [list args {
reply
after 100 [list [info coroutine]]
yield
reply 5
after 100 [list [info coroutine]]
yield
reply 10
reply -code break
reply 20
reply -code break
} [namespace current]]
coroutine c2 ::apply [list args {
variable res
yield
while 1 {
lappend new [call c1]
}
while 1 {
lappend new [call c1]
}
set res $new
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
return $res
} -cleanup [cleanup1] -result [sl {
5 10 20
}]
test error {} -setup {} -body {
variable res
coroutine c1 ::apply [list args {
reply
after 100 [list [info coroutine]]
yield
catch {abadcommand} cres copts
reply -options $copts $cres
} [namespace current]]
coroutine c2 ::apply [list args {
variable res
yield
catch {call c1} cres opts
lappend res [dict get $opts -code] $cres
} [namespace current]]
after 0 [list [namespace which c2]]
vwait [namespace current]::res
return $res
} -cleanup [cleanup1] -result [sl {
1 {invalid command name "abadcommand"}
}]
cleanupTests
}
|
Added packages/coro/lib/relay/71.