Differences From Artifact [6f3a26e84c]:
- File lib/threadpool/future.tcl — part of check-in [08a50e0d96] at 2019-07-26 18:48:41 on branch trunk — Comment tweaks (user: aku size: 4921)
To Artifact [99fb4c8fd3]:
- File
lib/threadpool/future.tcl
— part of check-in
[6a4d9b2499]
at
2019-07-26 22:09:10
on branch restructure-packages
— Replaced the old `Debug` package with Tcllib's `debug`. Updated all users.
Extended all applications with env variable processing for dynamic activation of debug tags.
Dropped auto_path shenanigans for tcllib, tklib. (user: aku size: 4909)
︙ | ︙ | |||
9 10 11 12 13 14 15 | ## defered through the event-loop. # ## Programing with futures is explicit continuation-passing-style. # ### ### ### ######### ######### ######### ## Requisites | | | | < | | | | | | | | | | | 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 | ## defered through the event-loop. # ## Programing with futures is explicit continuation-passing-style. # ### ### ### ######### ######### ######### ## Requisites package require debug package require debug::caller package require snit # ### ### ### ######### ######### ######### ## Narrative tracing debug level future debug prefix future {[debug caller] | } # ### ### ### ######### ######### ######### ## Implementation snit::type future { # ### ### ### ######### ######### ######### ## Class API ## Simplified construction with integrated setup # Provide new future configured with arguments. See `on ..`, # `nop`, `empty`, and `chain`. typemethod new {args} { debug.future {} set future [$type create %AUTO%] if {[llength $args]} { $future {*}$args } return $future } # Provide a new future in default configuration and trigger it to # return the args and the next idle point. Further configuration # can be done on the result object. typemethod return {args} { debug.future {} set f [$type new] after idle [list $f return {*}$args] return $f } # ### ### ### ######### ######### ######### ## API. Various configuration methods. Chainable. # Configure callback to invoke on `return`. method {on return} {cmdprefix args} { debug.future {} set myOkCmdPrefix $cmdprefix if {[llength $args]} { $self {*}$args } return $self } # Configure callback to invoke on `error`. method {on error} {cmdprefix args} { debug.future {} set myErrorCmdPrefix $cmdprefix if {[llength $args]} { $self {*}$args } return $self } # Clear all callbacks. The future will now swallow all its invokations. method nop {} { debug.future {} set myOkCmdPrefix {} set myErrorCmdPrefix {} return } # Same as nop. method empty {} { debug.future {} set myOkCmdPrefix {} set myErrorCmdPrefix {} return } # Configure callbacks to post invokations to the other future. method chain {future args} { debug.future {} # Inlined on return on error configuration chaining to another # future. set myOkCmdPrefix [list $future return] set myErrorCmdPrefix [list $future error] if {[llength $args]} { $self {*}$args } return $self } # ### ### ### ######### ######### ######### ## API. Invoke the future. This will destroy the instance as well. method error {message} { debug.future {} $self Error $message return } method return {args} { debug.future {} # Syntax: | 0 # : -code x | 2 # : -code x val | 3 # : val | 4 # Allowing multiple -code settings, last one is taken. set rcode 0 |
︙ | ︙ | |||
139 140 141 142 143 144 145 | # ### ### ### ######### ######### ######### ## Destruction. A user is not allowed to destroy instances. Can ## only be done by invoking it (return or error), as part of which ## it destroys itself. destructor { | | | | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | # ### ### ### ######### ######### ######### ## Destruction. A user is not allowed to destroy instances. Can ## only be done by invoking it (return or error), as part of which ## it destroys itself. destructor { debug.future {} if {$myIsDone} return return -code error "Illegal attempt to destroy unresolved future \"$self\"" } # ### ### ### ######### ######### ######### ## State variable myIsDone 0 variable myOkCmdPrefix {return -code return} variable myErrorCmdPrefix {return -code error} # ### ### ### ######### ######### ######### ## Helper commands. Invoke the configured callbacks, if any. This ## is also where the instance destroys itself. Note that callback ## execution is defered to the event loop. method Ok {result} { debug.future {[list ==> $myOkCmdPrefix]} set cmdprefix $myOkCmdPrefix DestroySelf if {![llength $cmdprefix]} return after 0 [list {*}$cmdprefix $result] return } method Error {message} { debug.future {[list ==> $myErrorCmdPrefix]} set cmdprefix $myErrorCmdPrefix DestroySelf if {![llength $cmdprefix]} return after 0 [list {*}$cmdprefix $message] return } proc DestroySelf {} { debug.future {} upvar 1 self self myIsDone myIsDone set myIsDone 1 $self destroy return } ## |
︙ | ︙ |