• Announcing Tasks 1.12

    From et4@21:1/5 to All on Tue May 17 22:33:43 2022
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl Programming Language" by Ashok Nadkarni, Tasks can take an independent procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large)
    fibonacci numbers 3-5 times faster than if done sequentially when run on
    a multi-core cpu:

    (example derived from Ashok's Promises blog)

    #----------------------------------------
    source tasks-1.12.tm
    namespace import tasks::*

    Tproc fibsize {number} {
    set fibnum [math::fibonacci $number]
    string length $fibnum
    } -tasks 5 [list {-package require math} ]

    tgroup fibsize -run 100000 100100 100200 100300 100400

    parray fibsize rvar,*
    #----------------------------------------

    Here, tgroup runs the 5 tasks (threads) concurrently and delivers the
    results to the array fibsize. [parray] then outputs the results.

    Tasks include several development tools including a handy 1 line Tk
    console and optionally one Tk window per task. It can send the same
    command to each singly or with patterns, to all or a specific group
    using task names.

    Note: a bug was discovered that can cause Tcl/Tk to crash in linux
    systems when running Tk in several threads. According to the ticket, it
    has been fixed, but I don't know which version the fix will be included
    in. For now, the code does not output using Tk but rather does puts to
    stdout. If you want to try it anyway, search for "hack 2" and comment
    out the incr statement. Its about line 51.

    Since task globals are partitioned by an interpreter, they are like
    namespace variables, and very easy to use. Included are list tools for
    global scalars, arrays, and a widget tree browser. Multiple monitors are
    a must.

    Tasks are source-able pure tcl. The wiki page at

    https://wiki.tcl-lang.org/page/Tasks

    provides all the documentation, examples and YouTube links to videos
    with intros and in-depth code walk-throughs to get you going with Tasks.

    The source is at GitHub at

    https://github.com/rocketship88/Tasks.git

    with a single-file tcl module named tasks-1.12.tm that can be sourced or
    if placed in an appropriate module folder loaded via package require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerald Lester@21:1/5 to All on Wed May 18 17:04:19 2022
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl Programming Language" by Ashok Nadkarni, Tasks can take an independent procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large) fibonacci numbers 3-5 times faster than if done sequentially when run on
    a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced or
    if placed in an appropriate module folder loaded via package require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.

    --
    +----------------------------------------------------------------------+
    | Gerald W. Lester, President, KNG Consulting LLC |
    | Email: Gerald.Lester@kng-consulting.net | +----------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Gerald Lester on Wed May 18 19:40:21 2022
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl
    Programming Language" by Ashok Nadkarni, Tasks can take an independent
    procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large)
    fibonacci numbers 3-5 times faster than if done sequentially when run
    on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced
    or if placed in an appropriate module folder loaded via package require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.


    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file that can
    be sourced. So, I'm not sure what benefit would be derived from it being
    in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of my 4
    yt videos on it, I think I have perhaps 2 views that aren't me and 1 of
    those is from my daughter who swears she watched the whole video but
    can't tell me anything about it :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arjen Markus@21:1/5 to All on Thu May 19 01:23:43 2022
    On Thursday, May 19, 2022 at 4:40:28 AM UTC+2, et4 wrote:
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl
    Programming Language" by Ashok Nadkarni, Tasks can take an independent
    procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large)
    fibonacci numbers 3-5 times faster than if done sequentially when run
    on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced
    or if placed in an appropriate module folder loaded via package require. >>
    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.

    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file that can
    be sourced. So, I'm not sure what benefit would be derived from it being
    in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of my 4
    yt videos on it, I think I have perhaps 2 views that aren't me and 1 of
    those is from my daughter who swears she watched the whole video but
    can't tell me anything about it :)
    I am not inclined to watch videos like this, I am afraid, but I do like the idea of this package and I want to explore it.

    One advantage of having it Tcllib is that it is part of a large collection of packages so people can more easily find it.

    Regards,

    Arjen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Arjen Markus on Thu May 19 09:54:11 2022
    On 5/19/2022 1:23 AM, Arjen Markus wrote:
    On Thursday, May 19, 2022 at 4:40:28 AM UTC+2, et4 wrote:
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl
    Programming Language" by Ashok Nadkarni, Tasks can take an independent >>>> procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be >>>> called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might >>>> be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large)
    fibonacci numbers 3-5 times faster than if done sequentially when run
    on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced
    or if placed in an appropriate module folder loaded via package require. >>>>
    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.

    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file that can
    be sourced. So, I'm not sure what benefit would be derived from it being
    in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of my 4
    yt videos on it, I think I have perhaps 2 views that aren't me and 1 of
    those is from my daughter who swears she watched the whole video but
    can't tell me anything about it :)
    I am not inclined to watch videos like this, I am afraid, but I do like the idea of this package and I want to explore it.

    One advantage of having it Tcllib is that it is part of a large collection of packages so people can more easily find it.

    Regards,

    Arjen

    Yeah, I'm definitely not the youtube star in my family, which would be
    my daughter who sings and has 500 followers :)

    I would then recommend reading the wiki page, especially the intro which
    is quite short.

    I had 2 goals when I started. I wanted to concentrate on using arglists
    vs. sending in scripts. And I wanted to code in a more sequential style
    than using event callbacks. I had looked into Ashok's promises, and I
    wanted to take a shot at my own abstraction.

    Since tcl threads don't directly share memory, they are closer to
    processes, and even processes use arglists (argc/argv). However, tsv is
    much more convenient and faster than other process to process
    communication and memory sharing (plus it's system independent).

    So, my task metaphor, is similar to processes but can use tsv. Unlike
    the thread package, which needs to be an all things to everyone kind of package, tasks are meant to do the 50-90% of the things you might want
    with simplicity, and well, there's always threads and tpool if tasks
    can't do it. I believe tasks are about as simple as I could make it.

    So, a task sits in a loop getting arglists from a queue, doing something
    with them, and returns a result. This can thus look like a server, e.g.
    an http request, but also looks like a procedure call. Using Ashok's
    method for sharing the queue, which I'd never had been able to code
    myself, tasks could now work as a team.

    The second goal was to be able to take any compute-hog procedure (and
    all it's called procedures) and get them loaded into a thread so the GUI
    in the mainthread would remain responsive. Using Ashok's proc
    reconstruct as a starting point lets me easily import procs into a
    thread. Of course, there's some thread support for that, but I really
    didn't quite understand tpool and ttrace.

    And since someone had the insight into providing a timeout in
    thread::cond one can use that while waiting for a job/arglist to arrive
    to service events as well. Yes, it's a polling mechanism, but when done
    inside your own thread, it's no biggy. This lets me have a responsive
    gui in each thread. It also lets me respond to thread::send from the
    outside. And that's especially useful for debugging, and so there's a
    console like task (may as well be in its own thread) that lifted some of
    the actual windows console code that does command and variable tab
    expansion.

    Initially I was going to support a wait for all jobs to complete AND a
    wait for one or a set of jobs, but I realized this was when an event was easier, and so I only have a wait for all. However, I can also do a
    write trace on a result variable for when I want to respond with events
    as each job finishes.

    But by NOT supporting more than a wait for all, I avoid all the job id's
    etc that are used in tpool. One of the examples demonstrates using a
    trace. And the code sets that up for you by just specifying a -N for the
    number of tasks. Also nice in tcl is that one can use the same name for
    a procedure and a variable with no conflicts. So, tasks use the same
    name for the trace callback proc and the array that gets the results if
    you do a wait for all. This avoids needing calls like tpool::get as well.

    Anyway, this was just some covid coding fun. But I wanted to share it,
    and so the wiki page and this announcement.

    I hope you find it useful.

    e

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerald Lester@21:1/5 to All on Thu May 19 16:50:41 2022
    On 5/19/22 11:54, et4 wrote:
    On 5/19/2022 1:23 AM, Arjen Markus wrote:
    On Thursday, May 19, 2022 at 4:40:28 AM UTC+2, et4 wrote:
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the >>>>> powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl >>>>> Programming Language" by Ashok Nadkarni, Tasks can take an independent >>>>> procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be >>>>> called several times.

    The Tasks proc-like arglist approach considerably reduces the need to >>>>> learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might >>>>> be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below >>>>> example a Tproc can compute the number of digits of 5 (rather large) >>>>> fibonacci numbers 3-5 times faster than if done sequentially when run >>>>> on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced >>>>> or if placed in an appropriate module folder loaded via package
    require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one >>>>> into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.

    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file that can >>> be sourced. So, I'm not sure what benefit would be derived from it being >>> in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of my 4 >>> yt videos on it, I think I have perhaps 2 views that aren't me and 1 of
    those is from my daughter who swears she watched the whole video but
    can't tell me anything about it :)
    I am not inclined to watch videos like this, I am afraid, but I do
    like the idea of this package and I want to explore it.

    One advantage of having it Tcllib is that it is part of a large
    collection of packages so people can more easily find it.

    Regards,

    Arjen

    Yeah, I'm definitely not the youtube star in my family, which would be
    my daughter who sings and has 500 followers :)

    I would then recommend reading the wiki page, especially the intro which
    is quite short.

    I had 2 goals when I started. I wanted to concentrate on using arglists
    vs. sending in scripts. And I wanted to code in a more sequential style
    than using event callbacks. I had looked into Ashok's promises, and I
    wanted to take a shot at my own abstraction.

    Since tcl threads don't directly share memory, they are closer to
    processes, and even processes use arglists (argc/argv). However, tsv is
    much more convenient and faster than other process to process
    communication and memory sharing (plus it's system independent).

    So, my task metaphor, is similar to processes but can use tsv. Unlike
    the thread package, which needs to be an all things to everyone kind of package, tasks are meant to do the 50-90% of the things you might want
    with simplicity, and well, there's always threads and tpool if tasks
    can't do it. I believe tasks are about as simple as I could make it.

    So, a task sits in a loop getting arglists from a queue, doing something
    with them, and returns a result. This can thus look like a server, e.g.
    an http request, but also looks like a procedure call. Using Ashok's
    method for sharing the queue, which I'd never had been able to code
    myself, tasks could now work as a team.

    The second goal was to be able to take any compute-hog procedure (and
    all it's called procedures) and get them loaded into a thread so the GUI
    in the mainthread would remain responsive. Using Ashok's proc
    reconstruct as a starting point lets me easily import procs into a
    thread. Of course, there's some thread support for that, but I really
    didn't quite understand tpool and ttrace.

    And since someone had the insight into providing a timeout in
    thread::cond one can use that while waiting for a job/arglist to arrive
    to service events as well. Yes, it's a polling mechanism, but when done inside your own thread, it's no biggy. This lets me have a responsive
    gui in each thread. It also lets me respond to thread::send from the
    outside. And that's especially useful for debugging, and so there's a
    console like task (may as well be in its own thread) that lifted some of
    the actual windows console code that does command and variable tab
    expansion.

    Initially I was going to support a wait for all jobs to complete AND a
    wait for one or a set of jobs, but I realized this was when an event was easier, and so I only have a wait for all. However, I can also do a
    write trace on a result variable for when I want to respond with events
    as each job finishes.

    But by NOT supporting more than a wait for all, I avoid all the job id's
    etc that are used in tpool. One of the examples demonstrates using a
    trace. And the code sets that up for you by just specifying a -N for the number of tasks. Also nice in tcl is that one can use the same name for
    a procedure and a variable with no conflicts. So, tasks use the same
    name for the trace callback proc and the array that gets the results if
    you do a wait for all. This avoids needing calls like tpool::get as well.

    Anyway, this was just some covid coding fun. But I wanted to share it,
    and so the wiki page and this announcement.

    Both Arjen are very familiar with Tcl tasks -- I did read your wiki
    page. I think the package is a good way for simple tasks and would be
    more widely used as part of TclLib.


    --
    +----------------------------------------------------------------------+
    | Gerald W. Lester, President, KNG Consulting LLC |
    | Email: Gerald.Lester@kng-consulting.net | +----------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Gerald Lester on Thu May 19 15:54:31 2022
    On 5/19/2022 2:50 PM, Gerald Lester wrote:
    On 5/19/22 11:54, et4 wrote:
    On 5/19/2022 1:23 AM, Arjen Markus wrote:
    On Thursday, May 19, 2022 at 4:40:28 AM UTC+2, et4 wrote:
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the >>>>>> powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl >>>>>> Programming Language" by Ashok Nadkarni, Tasks can take an
    independent
    procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need
    to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to >>>>>> learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks
    might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below >>>>>> example a Tproc can compute the number of digits of 5 (rather large) >>>>>> fibonacci numbers 3-5 times faster than if done sequentially when run >>>>>> on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be sourced >>>>>> or if placed in an appropriate module folder loaded via package
    require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one >>>>>> into concurrent programming to better utilize these new machines.

    Please consider submitting this to be a part of TclLib.

    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file that
    can
    be sourced. So, I'm not sure what benefit would be derived from it
    being
    in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of
    my 4
    yt videos on it, I think I have perhaps 2 views that aren't me and 1 of >>>> those is from my daughter who swears she watched the whole video but
    can't tell me anything about it :)
    I am not inclined to watch videos like this, I am afraid, but I do
    like the idea of this package and I want to explore it.

    One advantage of having it Tcllib is that it is part of a large
    collection of packages so people can more easily find it.

    Regards,

    Arjen

    Yeah, I'm definitely not the youtube star in my family, which would be
    my daughter who sings and has 500 followers :)

    I would then recommend reading the wiki page, especially the intro
    which is quite short.

    I had 2 goals when I started. I wanted to concentrate on using
    arglists vs. sending in scripts. And I wanted to code in a more
    sequential style than using event callbacks. I had looked into Ashok's
    promises, and I wanted to take a shot at my own abstraction.

    Since tcl threads don't directly share memory, they are closer to
    processes, and even processes use arglists (argc/argv). However, tsv
    is much more convenient and faster than other process to process
    communication and memory sharing (plus it's system independent).

    So, my task metaphor, is similar to processes but can use tsv. Unlike
    the thread package, which needs to be an all things to everyone kind
    of package, tasks are meant to do the 50-90% of the things you might
    want with simplicity, and well, there's always threads and tpool if
    tasks can't do it. I believe tasks are about as simple as I could make
    it.

    So, a task sits in a loop getting arglists from a queue, doing
    something with them, and returns a result. This can thus look like a
    server, e.g. an http request, but also looks like a procedure call.
    Using Ashok's method for sharing the queue, which I'd never had been
    able to code myself, tasks could now work as a team.

    The second goal was to be able to take any compute-hog procedure (and
    all it's called procedures) and get them loaded into a thread so the
    GUI in the mainthread would remain responsive. Using Ashok's proc
    reconstruct as a starting point lets me easily import procs into a
    thread. Of course, there's some thread support for that, but I really
    didn't quite understand tpool and ttrace.

    And since someone had the insight into providing a timeout in
    thread::cond one can use that while waiting for a job/arglist to
    arrive to service events as well. Yes, it's a polling mechanism, but
    when done inside your own thread, it's no biggy. This lets me have a
    responsive gui in each thread. It also lets me respond to thread::send
    from the outside. And that's especially useful for debugging, and so
    there's a console like task (may as well be in its own thread) that
    lifted some of the actual windows console code that does command and
    variable tab expansion.

    Initially I was going to support a wait for all jobs to complete AND a
    wait for one or a set of jobs, but I realized this was when an event
    was easier, and so I only have a wait for all. However, I can also do
    a write trace on a result variable for when I want to respond with
    events as each job finishes.

    But by NOT supporting more than a wait for all, I avoid all the job
    id's etc that are used in tpool. One of the examples demonstrates
    using a trace. And the code sets that up for you by just specifying a
    -N for the number of tasks. Also nice in tcl is that one can use the
    same name for a procedure and a variable with no conflicts. So, tasks
    use the same name for the trace callback proc and the array that gets
    the results if you do a wait for all. This avoids needing calls like
    tpool::get as well.

    Anyway, this was just some covid coding fun. But I wanted to share it,
    and so the wiki page and this announcement.

    Both Arjen are very familiar with Tcl tasks -- I did read your wiki
    page.  I think the package is a good way for simple tasks and would be
    more widely used as part of TclLib.



    I have no objections to it being part of tcllib, however, I haven't a
    clue how that would be accomplished.

    Is it anything like a TIP? In 20 years I've got 2 TIPs approved (they're
    in 8.7 finally) but I still don't know how to create a TIP myself. And
    the one I really wanted never even got to the TIP stage.

    But if anyone wants to grab the code and submit it, I have no
    objections. I'm quite a novice at github, but I can grant any access to
    anyone if I'm told how.

    If it's in tcllib, how is it maintained? Does it need a real manual? I'm getting a bit old in the tooth to be able to do much more (now in my 4th quarter century). I code only for fun, and have to limit the time in
    front of my computers.

    But I did just build a super cool new machine, an intel i7-12700k with
    12 cores and 20 threads. With tasks, I can peg the machine till it
    screams :)

    Like this:



    tcl::tm::path add d:/stuff
    package require tasks 1.13
    namespace import tasks::*

    console show

    Tproc peg {x} {
    xwait $x ;# busy wait
    putz "after $x inside $::t_name" red
    } -tasks 20 -import_tasks -once [list {-set t_debug 2 ;# to console}]

    set x 5000
    tgroup peg -call $x

    after [expr { $x + 4000 }] {tdump xxx} ;# still running ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to All on Thu May 19 21:08:08 2022
    On 5/19/2022 3:54 PM, et4 wrote:
    On 5/19/2022 2:50 PM, Gerald Lester wrote:
    On 5/19/22 11:54, et4 wrote:
    On 5/19/2022 1:23 AM, Arjen Markus wrote:
    On Thursday, May 19, 2022 at 4:40:28 AM UTC+2, et4 wrote:
    On 5/18/2022 3:04 PM, Gerald Lester wrote:
    On 5/18/22 00:33, et4 wrote:
    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using >>>>>>> the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl >>>>>>> Programming Language" by Ashok Nadkarni, Tasks can take an
    independent
    procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need >>>>>>> to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the
    need to
    learn new concepts. If you've wanted to dive into the Tcl threads >>>>>>> package but haven't had the time to study the manual, then Tasks >>>>>>> might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below >>>>>>> example a Tproc can compute the number of digits of 5 (rather large) >>>>>>> fibonacci numbers 3-5 times faster than if done sequentially when >>>>>>> run
    on a multi-core cpu:
    ...

    with a single-file tcl module named tasks-1.12.tm that can be
    sourced
    or if placed in an appropriate module folder loaded via package
    require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one >>>>>>> into concurrent programming to better utilize these new machines. >>>>>>
    Please consider submitting this to be a part of TclLib.

    Thanks for the feedback. Not sure what that would entail. And it's
    available from github; I specified no-license.

    It conforms to the tcl module definition, meaning a single file
    that can
    be sourced. So, I'm not sure what benefit would be derived from it
    being
    in the tcllib.

    But thanks for suggesting it. Perhaps after I get some feedback. Of
    my 4
    yt videos on it, I think I have perhaps 2 views that aren't me and
    1 of
    those is from my daughter who swears she watched the whole video but >>>>> can't tell me anything about it :)
    I am not inclined to watch videos like this, I am afraid, but I do
    like the idea of this package and I want to explore it.

    One advantage of having it Tcllib is that it is part of a large
    collection of packages so people can more easily find it.

    Regards,

    Arjen

    Yeah, I'm definitely not the youtube star in my family, which would
    be my daughter who sings and has 500 followers :)

    I would then recommend reading the wiki page, especially the intro
    which is quite short.

    I had 2 goals when I started. I wanted to concentrate on using
    arglists vs. sending in scripts. And I wanted to code in a more
    sequential style than using event callbacks. I had looked into
    Ashok's promises, and I wanted to take a shot at my own abstraction.

    Since tcl threads don't directly share memory, they are closer to
    processes, and even processes use arglists (argc/argv). However, tsv
    is much more convenient and faster than other process to process
    communication and memory sharing (plus it's system independent).

    So, my task metaphor, is similar to processes but can use tsv. Unlike
    the thread package, which needs to be an all things to everyone kind
    of package, tasks are meant to do the 50-90% of the things you might
    want with simplicity, and well, there's always threads and tpool if
    tasks can't do it. I believe tasks are about as simple as I could
    make it.

    So, a task sits in a loop getting arglists from a queue, doing
    something with them, and returns a result. This can thus look like a
    server, e.g. an http request, but also looks like a procedure call.
    Using Ashok's method for sharing the queue, which I'd never had been
    able to code myself, tasks could now work as a team.

    The second goal was to be able to take any compute-hog procedure (and
    all it's called procedures) and get them loaded into a thread so the
    GUI in the mainthread would remain responsive. Using Ashok's proc
    reconstruct as a starting point lets me easily import procs into a
    thread. Of course, there's some thread support for that, but I really
    didn't quite understand tpool and ttrace.

    And since someone had the insight into providing a timeout in
    thread::cond one can use that while waiting for a job/arglist to
    arrive to service events as well. Yes, it's a polling mechanism, but
    when done inside your own thread, it's no biggy. This lets me have a
    responsive gui in each thread. It also lets me respond to
    thread::send from the outside. And that's especially useful for
    debugging, and so there's a console like task (may as well be in its
    own thread) that lifted some of the actual windows console code that
    does command and variable tab expansion.

    Initially I was going to support a wait for all jobs to complete AND
    a wait for one or a set of jobs, but I realized this was when an
    event was easier, and so I only have a wait for all. However, I can
    also do a write trace on a result variable for when I want to respond
    with events as each job finishes.

    But by NOT supporting more than a wait for all, I avoid all the job
    id's etc that are used in tpool. One of the examples demonstrates
    using a trace. And the code sets that up for you by just specifying a
    -N for the number of tasks. Also nice in tcl is that one can use the
    same name for a procedure and a variable with no conflicts. So, tasks
    use the same name for the trace callback proc and the array that gets
    the results if you do a wait for all. This avoids needing calls like
    tpool::get as well.

    Anyway, this was just some covid coding fun. But I wanted to share
    it, and so the wiki page and this announcement.

    Both Arjen are very familiar with Tcl tasks -- I did read your wiki
    page.  I think the package is a good way for simple tasks and would be
    more widely used as part of TclLib.



    I have no objections to it being part of tcllib, however, I haven't a
    clue how that would be accomplished.

    Is it anything like a TIP? In 20 years I've got 2 TIPs approved (they're
    in 8.7 finally) but I still don't know how to create a TIP myself. And
    the one I really wanted never even got to the TIP stage.

    But if anyone wants to grab the code and submit it, I have no
    objections. I'm quite a novice at github, but I can grant any access to anyone if I'm told how.

    If it's in tcllib, how is it maintained? Does it need a real manual? I'm getting a bit old in the tooth to be able to do much more (now in my 4th quarter century). I code only for fun, and have to limit the time in
    front of my computers.

    But I did just build a super cool new machine, an intel i7-12700k with
    12 cores and 20 threads. With tasks, I can peg the machine till it
    screams :)

    Like this:



    tcl::tm::path add d:/stuff
    package require tasks   1.13
    namespace import tasks::*

    console show

    Tproc peg {x} {
        xwait $x ;# busy wait
        putz "after $x inside $::t_name" red
    } -tasks 20 -import_tasks -once [list {-set t_debug 2 ;# to console}]

    set x 5000
    tgroup peg -call $x

    after [expr {   $x + 4000   }] {tdump xxx} ;# still running ?





    Well, it appears I've messed up on github. I thought no-license meant
    public domain but someone asked me if it was MIT or Tcl/Tk. So, I
    googled and it said no license means nobody can use it.

    Then I thought, uh oh, I have some snippets of wiki code that I've used
    before and even some code from the tk console.

    In order for others to freely use the code, what license should I use
    and can I simply change that somewhere on github.

    I only moved to github from the wiki after I sorta broke the wiki. One
    day when I moved code from one place to another, the wiki froze when I
    asked for diffs. A week later, it gave me an error when I asked for a
    history diff.

    I had assumed that wiki code could be freely used, modified, and placed
    back on the wiki. However, now that I've had to move it to github, it
    seems I've entered lawyer land.

    Oh my, it was so much easier when I started on punchcards in the 60's.
    No software patents or licenses to worry about. I guess it's true, no
    good deed goes unpunished.

    Any advice?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From apn@21:1/5 to All on Fri May 20 10:29:56 2022
    On 5/20/2022 9:38 AM, et4 wrote:
    Oh my, it was so much easier when I started on punchcards in the 60's.
    No software patents or licenses to worry about. I guess it's true, no
    good deed goes unpunished.

    Any advice?



    It's easy enough on github. Either add a LICENSE file in your work tree,
    commit and push to github. Or even easier, click on the Add File button
    in the github code page, click Create File, on the create file page type LICENSE as the file name. A button "choose license template" will then automatically appear on the right side. Click that, choose an
    appropriate license (one of the BSD ones is most common for Tcl
    extensions), then at the bottom choose the radio button that says
    "commit to master" or something like that (not the one to create a
    branch), then click the commit button.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to apn on Thu May 19 23:58:14 2022
    On 5/19/2022 9:59 PM, apn wrote:
    On 5/20/2022 9:38 AM, et4 wrote:
    Oh my, it was so much easier when I started on punchcards in the 60's.
    No software patents or licenses to worry about. I guess it's true, no
    good deed goes unpunished.

    Any advice?



    It's easy enough on github. Either add a LICENSE file in your work tree, commit and push to github. Or even easier, click on the Add File button
    in the github code page, click Create File, on the create file page type LICENSE as the file name. A button "choose license template" will then automatically appear on the right side. Click that, choose an
    appropriate license (one of the BSD ones is most common for Tcl
    extensions), then at the bottom choose the radio button that says
    "commit to master" or something like that (not the one to create a
    branch), then click the commit button.

    Whew! Great directions. Much appreciate that. I chose MIT as it was
    kinda being flashed in lights on the which to choose page.

    So, type the magic word and the genie appears. I guess that's for some
    legal reason, why not just a button in plain sight.

    I was put a bit off balance by the issuer's name, foobar73, a bot maybe?

    So the other worrisome point is with the code I lifted out of the tk
    console for tab expansion. And I used a number of RS's Wiki snippets,
    like his simple menu code. There was a section in the explanation about
    using something that had a different license and other confusions.

    It was much easier when I could keep the code on the wiki. Maybe I could
    just create a separate page for it. That might get past the too big
    limit I'd broken.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Fri May 20 14:07:12 2022
    On 5/19/22 12:54 PM, et4 wrote:

    I had 2 goals when I started. I wanted to concentrate on using arglists
    vs. sending in scripts. And I wanted to code in a more sequential style
    than using event callbacks.


    Hello,

    Interesting project. Can you expand on the distinction between arglist
    and scripts?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to saitology9@gmail.com on Fri May 20 15:45:52 2022
    On 5/20/2022 11:07 AM, saitology9@gmail.com wrote:
    On 5/19/22 12:54 PM, et4 wrote:

    I had 2 goals when I started. I wanted to concentrate on using
    arglists vs. sending in scripts. And I wanted to code in a more
    sequential style than using event callbacks.

    Hello,

    Interesting project. Can you expand on the distinction between arglist
    and scripts?

    Great question! It comes down to familiarity. The expert won't have any
    trouble with the distinction, but a beginner might find the Tasks implementation looks a bit more like what they are used to.

    When you call a procedure (or method, or a built in command) you do
    something like,

    string range $a 1 end

    or

    proc myproc {x y z} {
    return [expr { $x + $y + $z }]
    }
    myproc 1 2 3 ;# returns 6

    Here the command or procedure arguments form an arglist (list of args).

    There is also the handy operator as well, the {*} which works on arglists.

    It becomes more clear when the procedure myproc is using the special
    args variable in say,

    proc myproc {args} {
    return [tcl::mathop::+ {*}$args]
    }


    set myargs {5 10 15}

    myproc {*}$myargs ;# produce 30

    So, a list of arguments can be passed around easily, and expanded on a
    command line. So args and {*} are sorta inverses, or at least that's how
    I think of them.


    When you want to send some work to a thread with thread::send, you send
    it a script, i.e. a command that it is going to execute. Perhaps
    something like,

    thread::send $theid {set somevar "some value"}


    With thread::create and then thread::send, I suppose you can achieve the
    same with myproc, but it is done a bit differently:


    set tid [thread::create {
    proc myproc {x y z} {
    return [expr { $x + $y + $z }]
    }
    thread::wait
    }]
    thread::send $tid {myproc 1 2 3} rvar1 ;# returns 6 to rvar1
    thread::send $tid {myproc 2 4 6} rvar2 ;# returns 12 to rvar2

    But suppose you have some data in lists and you want to send them to a
    set of threads to work on concurrently,

    lassign {10 20 30} x y z
    {1 2 3}
    {4 5 6}
    [list $x $y $z]

    you will have to include the myproc with this to send it in as a script.
    And you will likely need to use tpool as well to create 3 threads if you
    want all 3 to run concurrently.

    Perhaps it's not as much of a difference as I once thought. But it just
    seems to be more clear and familiar when you are just working with the
    args and it looks like a regular procedure. And so, with tasks, you'd create

    Tproc myproc {args} {
    return [tcl::mathop::+ {*}$args]
    } -tasks 3

    and run them concurrently:

    tgroup myproc -run {1 2 3} {4 5 6} [list $x $y $z]
    parray myproc rvar*

    This would produce from the parray command:

    myproc(rvar,0) = 6
    myproc(rvar,1) = 15
    myproc(rvar,2) = 60

    And so you didn't have to deal with the myproc in each set of args.
    Maybe no biggy, certainly not for the expert, but perhaps a beginner
    might find it a bit more comfortable.

    and if you happen to have these 3 sets of arglists in a list variable,
    say my3,

    lassign {100 200 300} x y z
    set my3 [list {10 20 30} {40 50 60} [list $x $y $z]]

    tgroup myproc -run {*}$my3
    parray myproc rvar*

    myproc(rvar,0) = 60
    myproc(rvar,1) = 150
    myproc(rvar,2) = 600


    This might come about if you were working with sets of 3d coordinates.

    But where I think the biggest advantage is in the ease of converting
    myproc from a simple procedure into a set of threads. You don't have to
    work with tpool and job ids. The -run option automatically waits for all
    3 jobs to complete but they each ran in a separate thread concurrently.
    The results can be extracted easily from the array myproc as well
    without having to call on the tpool::get and keep track of the job ids.

    And I think it is rare that one wants to wait for only a subset of the
    results, rather than to wait for them all. If that's the case, tasks can
    place a trace on each of the rvar,* array elements and get an event
    callback as each completes.

    There was a recent thread where someone had difficulty with managing the
    job ids and the answer was:

    If you want to wait for all jobs to be ready, you have to call
    tpool::wait in a loop. Something like this:

    while {[llength $jobs]} {
    tpool::wait $pool $jobs jobs
    }

    Easy enough for a seasoned tcl programmer and elegantly done. But I had
    to simulate it in my mind to see what it was doing. That's why I created
    tasks, because I have trouble with these sorts of scripts. I recall a cs
    course on APL way back in college; I had a lot of trouble with that
    language. A lot going on at once.

    Maybe others are also like me.

    If you were computing something more cpu-intensive, using separate
    threads could give you a large boost in performance with a modern
    multi-core cpu chip. In 10 years we likely will be seeing core counts of
    64 or 128 or even higher. My 12 core 20 thread chip only cost me $320 on
    sale at amazon.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to All on Sat May 21 04:50:54 2022
    On 5/20/2022 3:45 PM, et4 wrote:


    Maybe others are also like me.


    Hmmm, I hope not. I've been locked up alone so long my social skills are
    gone. Please accept my apology for such a long and possibly irritating
    rant.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Sat May 21 11:26:51 2022
    On 5/20/22 6:45 PM, et4 wrote:

    Great question! It comes down to familiarity. The expert won't have any trouble with the distinction, but a beginner might find the Tasks implementation looks a bit more like what they are used to.


    Hello,

    Thank you for the detailed response. I thought you were somehow avoiding sending any scripts to the threads. It looks like you're simplifying
    that process via your Tproc's and managing the rest with arglists.

    BTW, perhaps you could package-enable it by adding a "package provide
    Tasks" or something similar in your code.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to saitology9@gmail.com on Sat May 21 19:09:44 2022
    On 5/21/2022 8:26 AM, saitology9@gmail.com wrote:
    On 5/20/22 6:45 PM, et4 wrote:

    Great question! It comes down to familiarity. The expert won't have
    any trouble with the distinction, but a beginner might find the Tasks
    implementation looks a bit more like what they are used to.


    Hello,

    Thank you for the detailed response. I thought you were somehow avoiding sending any scripts to the threads.  It looks like you're simplifying
    that process via your Tproc's and managing the rest with arglists.

    BTW, perhaps you could package-enable it by adding a "package provide
    Tasks" or something similar in your code.



    You can use a package require on tasks-1.12.tm since that file name
    defines a module. You can either place it in a module directory that
    should already exist, or you can use a tcl::tm::path add command, just
    like appending to auto_path.

    I didn't know about tcl modules until I read Ashok's book. There was a
    TIP for moudles some time back.

    I'm glad you didn't hate my response, I usually hate them after I write
    them. Too bad you can't edit them, like on the wiki. Ignore the below if
    you want, but I can't resist describing the design of Tasks, and perhaps
    answer arglist vs. scripts better.


    Second try, more to the point, but I don't know about shorter. There's
    just too much to describe. I love tcl and everything about it. I was
    hoping that Tasks might recruit programmers from other languages. I
    guess it depends on if I did a good job.

    I wanted to treat a thread as a concurrent procedure. I'm not a go user,
    but I think their go-routines might be closest to what I was looking for.

    Tasks have 5 primitives: create the task and 2 pairs to handle the 2
    sides, caller and callee. Tproc and Tgroup calls use them, but they can
    also be used by themselves.

    The Task creates a single thread, adds to whatever script is supplied,
    and provides a queue to receive arglists.

    Task name ?options? ?import list & initializers? {
    script
    }

    The script is often just a variable, but can be inline.

    I wanted to mimic a procedure with a task, so it has 2 procs that you call:

    twait -> arg1 arg2 ...
    treturn value

    The twait uses mutexes and condition variables to block the task till
    there's something in the queue. The -> is just the first arg to twait,
    and receives the next arglist from the queue. argv, args, etc. can also
    be used. I just like how it looks, another great tcl feature. After it
    gets the arglist, it lassigns them to the arg1 arg2 ...

    So, here we have an arglist, not a script.

    The script code works on the args, just like a proc.

    Results are then sent back to the caller with treturn. Just like with thread::send, there's a return variable to synchronize the sending back,
    even with -async calls, so required.

    These 2 are in a forever loop. So, we're not waiting for events, we're
    running sequential code. We can use after/vwait to create delays, handle
    event callbacks etc. But we don't go to the next job until we
    sequentially come back to the top of the loop and do another twait.

    One advantage of using your own queue, is it's visibility, and included debugging tools let you see it's size and contents and/or trace each
    action on the queue.

    On the other side, the client or caller, we have the second pair of
    primitives:

    tcall $taskname ?-async? resultvar <- arg1 arg2 ...

    and if called -async

    tvwait resultvar

    The <- is optional and ignored if present. Again, for looks only.

    And that's it for the gutz of Tasks.




    So, by concentrating on arglists, it looks like a standard sequential procedure.

    Built on top of that is tgroup. It calls Task N times (as supplied in
    -tasks N) to create N tasks. However, all N share one queue. Again, a
    queue of arglists.

    tgroup also can send multiple sets of arglists to the queue, -async, and
    then wait for them (or not). There's a tgroup option to eventually wait
    for all to complete. If some have already completed, no problem, it just
    goes on the the next one. By waiting on all, the order of each wait
    doesn't matter. tgroup can also setup trace callbacks as each finishes.

    Tproc uses proc to create a procedure using the first 3 args. Then it
    calls tgroup to create N tasks, with any imports or initializers that
    tgroup then passed on to Tasks. The proc it created is imported to each
    thread.

    Tproc supplies a 2 line script, that passes an arglist on to the
    imported proc, and then returns the value that it returns:

    twait args
    treturn [name {*}args]

    So, as you can see, the emphasis is on arglists, not scripts. Of course
    at the level where Tasks uses the thread package, it's sending scripts.
    It also uses tsv to store all details about tasks.

    Hope I better answered the question about scripts vs. arglists.

    One bragging point. Because Tproc looks like a regular proc with a few
    extra options, and can be used with tgroup w/o one ever reading anything
    about threads, I like to say that one can write (some kinds of)
    concurrent code by learning only 1 1/2 new commands.

    Forgive me for posting so much, I just love to show what one can do with
    the tcl language.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to All on Sat May 21 22:18:13 2022
    On 5/21/2022 7:09 PM, et4 wrote:

    One bragging point.

    There I go again. Meant to say bragging on other message boards about tcl.

    I also dropped a $ in:

    twait args
    treturn [name {*}$args]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to saitology9@gmail.com on Sun May 22 00:07:15 2022
    On 5/21/2022 8:26 AM, saitology9@gmail.com wrote:


    BTW, perhaps you could package-enable it by adding a "package provide
    Tasks" or something similar in your code.


    Interesting, Ashok does say you *need* a package provide in a module.
    But I can package require it w/o that. Also, if when I do add one and
    give it a different version than the file name, it errors out.

    So, I guess I don't understand why it's needed. The only version one can specify must be encoded in the file name, so wouldn't it make sense for
    the package command to assume that's what it is providing?

    Anyway, it's easy enough to tack on to the end of the file, so I will do
    it - thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From apn@21:1/5 to All on Sun May 22 15:48:40 2022
    On 5/22/2022 12:37 PM, et4 wrote:
    Interesting, Ashok does say you *need* a package provide in a module.
    But I can package require it w/o that. Also, if when I do add one and
    give it a different version than the file name, it errors out.

    I'm not sure why I said that. Either I was mistaken or the reason has
    been flushed out of my memory buffer.

    /Ashok

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Sun May 22 11:36:20 2022
    On 5/22/22 3:07 AM, et4 wrote:

    Interesting, Ashok does say you *need* a package provide in a module.
    But I can package require it w/o that. Also, if when I do add one and
    give it a different version than the file name, it errors out.

    So, I guess I don't understand why it's needed. The only version one can specify must be encoded in the file name, so wouldn't it make sense for
    the package command to assume that's what it is providing?

    Anyway, it's easy enough to tack on to the end of the file, so I will do
    it - thanks.

    Hello,

    The package require commands do not work. When you explicitly add the do tcl::tm::path add, then package require succeeds, but Tproc is still not recognized.

    The only way I could get it to work is by doing:

    source tasks-tasks-1.12.tm
    namespace import tasks::*

    While my knowledge of Tcl may be slightly dated, I don't recall ever
    using anything other than a package require; so something is amiss here.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Sun May 22 11:45:31 2022
    On 5/21/22 10:09 PM, et4 wrote:

    I'm glad you didn't hate my response, I usually hate them after I write
    them. Too bad you can't edit them, like on the wiki. Ignore the below if
    you want, but I can't resist describing the design of Tasks, and perhaps answer arglist vs. scripts better.



    Hello,

    A number of years ago, I implemented something quite similar. It was
    part of an existing system so I didn't design it to be a package but it
    could have been. There were some challenges and I don't recall the
    details enough to mention them now. Your description refreshed my memory
    a bit.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to saitology9@gmail.com on Sun May 22 18:10:12 2022
    On 5/22/2022 8:36 AM, saitology9@gmail.com wrote:

    The only way I could get it to work is by doing:

    source tasks-tasks-1.12.tm
    namespace import tasks::*


    Can I assume you didn't use tasks-tasks-1.12.tm as you state?

    What did you actually try with a package require command?

    The file name has to be exactly as in the download tasks-1.12.tm and in
    my case has to be in the folder I specify:

    Typically, I will do this if I don't want to namespace import:


    tcl::tm::path add d:/stuff ;# add to the list of module paths
    set zzz [package require -exact tasks 1.12]
    puts "package = $zzz"

    catch {console show}

    tasks::Tproc foo {a} {
    incr a
    return $a
    } -tasks 1 ;# default is 4 otherwise

    tasks::tgroup foo -run 10 20 30

    tasks::tdump .* 20 ;# limit output width to 20

    parray foo args*
    puts ""
    parray foo rvar*

    which will output this to the console (or terminal on linux but need to
    change the path on linux)


    package = 1.12

    ------ Task(s) dump -----------------------------------------
    tsv::names = |main tvar tids|
    tsv::tids = |tid00002BC4 tid00002E64| ---------------------------------------------------------------
    tid/names = |tid00002BC4 foo0 tid00002E64 mainthread| ---------------------------------------------------------------
    foo0 tid: tid00002BC4 exists: 1
    (foo0,cond) = |cid1|
    (foo0,count) = |3|
    (foo0,error) = ||
    (foo0,gvar) = |::foo(rvar,2)|
    (foo0,mutex) = |mid0|
    (foo0,pid) = |tid00002E64|
    (foo0,putz) = ||
    (foo0,queue) = ||
    (foo0,result) = |31|
    (foo0,script) = |if [catch {⤶#Preamble|
    (foo0,share) = ||
    (foo0,tid) = |tid00002BC4|
    (foo0,user) = ||
    mainthread tid: tid00002E64 exists: 1 ---------------------------------------------------------------
    foo(args,0) = 10
    foo(args,1) = 20
    foo(args,2) = 30

    foo(rvar,0) = 11
    foo(rvar,1) = 21
    foo(rvar,2) = 31

    ---------------------------------------------


    or with the namespace import and on linux:

    tcl::tm::path add [pwd] ;# add to the list of module paths
    set zzz [package require -exact tasks 1.12]
    puts "zzz= |$zzz| "

    namespace import tasks::*

    Tproc foo {a} {
    incr a
    return $a
    } -tasks 1 ;# default is 4 otherwise
    tgroup foo -run 100 20 30

    tdump .* 20 ;# limit output width

    parray foo args*
    puts ""
    parray foo rvar*



    [1913]$ time tclsh wiki-example2.tcl
    zzz= |1.12|

    ------ Task(s) dump -----------------------------------------
    tsv::names = |main tvar tids|
    tsv::tids = |tid0x7fe533682700 tid0x7fe53458d740| ---------------------------------------------------------------
    tid/names = |tid0x7fe533682700 foo0 tid0x7fe53458d740 mainthread| ---------------------------------------------------------------
    foo0 tid: tid0x7fe533682700 exists: 1
    (foo0,cond) = |cid1|
    (foo0,count) = |3|
    (foo0,error) = ||
    (foo0,gvar) = |::foo(rvar,2)|
    (foo0,mutex) = |mid0|
    (foo0,pid) = |tid0x7fe53458d740|
    (foo0,putz) = ||
    (foo0,queue) = ||
    (foo0,result) = |31|
    (foo0,script) = |if [catch {⤶#Preamble|
    (foo0,share) = ||
    (foo0,tid) = |tid0x7fe533682700|
    (foo0,user) = ||
    mainthread tid: tid0x7fe53458d740 exists: 1 ---------------------------------------------------------------
    foo(args,0) = 100
    foo(args,1) = 20
    foo(args,2) = 30

    foo(rvar,0) = 101
    foo(rvar,1) = 21
    foo(rvar,2) = 31

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Sun May 22 21:28:02 2022
    On 5/22/22 9:10 PM, et4 wrote:

    Can I assume you didn't use tasks-tasks-1.12.tm as you state?

    What did you actually try with a package require command?

    The file name has to be exactly as in the download tasks-1.12.tm and in
    my case has to be in the folder I specify:



    Hello,

    It is no problem really and I don't want to keep you busy with idletasks
    :-) This is what I just did (within the same tclsh session):

    ... I cd into the folder containing the tasks file ...

    % tcl::tm::path add .
    % package require tasks-1.12.tm
    can't find package tasks-1.12.tm


    Alternative try:
    % source tasks-1.12.tm
    % Tproc
    invalid command name "Tproc"


    Working version:
    % namespace import tasks::*
    % Tproc
    wrong # args: should be "Tproc name arguments body ?option? ?num? ?arg ...?"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@gmail.com@21:1/5 to All on Sun May 22 21:42:50 2022
    On 5/22/22 9:10 PM, et4 wrote:

        tasks::Tproc foo {a} {
            incr a
            return $a
        } -tasks 1 ;# default is 4 otherwise


    Please ignore my post: I just realized that I wasn't using the namespace prefix; which was the source of the confusion.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to saitology9@gmail.com on Sun May 22 18:50:19 2022
    On 5/22/2022 6:28 PM, saitology9@gmail.com wrote:

    % tcl::tm::path add .
    % package require tasks-1.12.tm
    can't find package tasks-1.12.tm



    It should be

    package require tasks 1.12

    it wants the package name a space and the version. I don't know the
    exact way it searches, but from what I read, it tries to find a module
    using the name, tasks, and the version, by constructing a file name out
    of that and so ends up with

    tasks-1.12.tm

    And thank you for trying it. You are the first feedback that I've had
    from a true user. Don't think you are wasting my time. You've even given
    me something to add to the documentation.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave@21:1/5 to All on Sun May 22 21:56:30 2022
    package ifneeded tasks 1.12 [string map [list @ $dir] {
    source [file join {@} tasks-1.12.tm]
    namespace import tasks::*
    package provide tasks 1.12
    }]


    --
    computerjock AT mail DOT com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Dave on Sun May 22 21:09:42 2022
    On 5/22/2022 7:56 PM, Dave wrote:
    package ifneeded tasks 1.12 [string map [list @ $dir] {
      source [file join {@} tasks-1.12.tm]
      namespace import tasks::*
      package provide tasks 1.12
    }]



    Do you have to be su for that to work? I get an error about $dir on both windows and linux. Or does that not work with modules?

    On windows, none of paths work, since I only use tclkits.


    On my linux system if I become su and copy the file tasks-1.12.tm to /usr/share/tcltk/tcl8.6/tcl8 and give it the appropriate file
    permissions (which I cheated on with 777) one can then load it with a
    package require tasks

    that directory has (now):

    root@pop-os:/usr/share/tcltk/tcl8.6/tcl8# ls -al
    total 380
    drwxr-xr-x 3 root root 4096 May 22 20:57 .
    drwxr-xr-x 7 root root 4096 May 5 2019 ..
    -rw-r--r-- 1 root root 108619 Feb 23 2019 http-2.9.0.tm
    -rw-r--r-- 1 root root 33935 Feb 23 2019 msgcat-1.6.1.tm
    drwxr-xr-x 2 root root 4096 May 5 2019 platform
    -rw-r--r-- 1 root root 10012 Feb 23 2019 platform-1.0.14.tm
    -rwxrwxrwx 1 root root 113897 May 22 20:57 tasks-1.12.tm
    -rw-r--r-- 1 root root 101389 Feb 23 2019 tcltest-2.5.0.tm

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to All on Mon May 23 11:31:22 2022
    On 23/05/2022 06:09, et4 wrote:
    On 5/22/2022 7:56 PM, Dave wrote:
    package ifneeded tasks 1.12 [string map [list @ $dir] {
       source [file join {@} tasks-1.12.tm]
       namespace import tasks::*
       package provide tasks 1.12
    }]



    Do you have to be su for that to work? I get an error about $dir on both windows and linux. Or does that not work with modules?


    Dave probably intended his code to be placed in a pkgIndex.tcl file to
    satisfy the old package mechanism. But with Tcl modules that is totally unnecessary. The whole point of modules is that you only need a single
    file. (That, and a less disk-intensive search mechanism.)


    Schelte.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to All on Mon May 23 11:37:15 2022
    On 22/05/2022 09:07, et4 wrote:
    On 5/21/2022 8:26 AM, saitology9@gmail.com wrote:


    BTW, perhaps you could package-enable it by adding a "package provide Tasks" or something similar in your code.


    Anyway, it's easy enough to tack on to the end of the file, so I will do > it - thanks.
    It's unnecessary. And the way you did it, by including the version
    number, it became a maintenance burden. When the version number number
    changes, you now have to remember to update it in two places. I suggest
    to remove it again. I never include a [package provide] command in my
    modules and they work fine.


    Schelte.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave@21:1/5 to All on Mon May 23 09:24:18 2022
    On 5/22/2022 11:09 PM, et4 wrote:
    On 5/22/2022 7:56 PM, Dave wrote:
    package ifneeded tasks 1.12 [string map [list @ $dir] {
    source [file join {@} tasks-1.12.tm]
    namespace import tasks::*
    package provide tasks 1.12
    }]



    Do you have to be su for that to work? I get an error about $dir on both windows and linux. Or does that not work with modules?

    On windows, none of paths work, since I only use tclkits.


    Part of your discussion seemed to be how to turn the .TM into a package.
    I'm using 8.6.11 on win7x64 -- not a tclkit. Putting the .TM and the
    above pkgIndex.tcl into ...\Tcl\lib\tasks successfully makes "tasks"
    able to be loaded from "package require tasks", and the Tproc procedure successfully imported.

    While .TM's may be more efficient, I prefer stuff to be in one place: \lib

    Just thought I'd share what worked for me.


    --
    computerjock AT mail DOT com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Schelte on Mon May 23 10:13:36 2022
    On 5/23/2022 2:37 AM, Schelte wrote:
    On 22/05/2022 09:07, et4 wrote:
    On 5/21/2022 8:26 AM, saitology9@gmail.com wrote:


    BTW, perhaps you could package-enable it by adding a "package provide
    Tasks" or something similar in your code.


    Anyway, it's easy enough to tack on to the end of the file, so I will
    do  > it - thanks.
    It's unnecessary. And the way you did it, by including the version
    number, it became a maintenance burden. When the version number number changes, you now have to remember to update it in two places. I suggest
    to remove it again. I never include a [package provide] command in my
    modules and they work fine.


    Schelte.

    Ok, that makes sense. I'll dump it. But hey, I think I finally got the
    hang of github releases from the practice :)

    Let me know if you got it working. I'd love to hear about any problems
    and successes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Dave on Mon May 23 10:09:36 2022
    On 5/23/2022 7:24 AM, Dave wrote:
    On 5/22/2022 11:09 PM, et4 wrote:
    On 5/22/2022 7:56 PM, Dave wrote:
    package ifneeded tasks 1.12 [string map [list @ $dir] {
       source [file join {@} tasks-1.12.tm]
       namespace import tasks::*
       package provide tasks 1.12
    }]



    Do you have to be su for that to work? I get an error about $dir on both
    windows and linux. Or does that not work with modules?

    On windows, none of paths work, since I only use tclkits.


    Part of your discussion seemed to be how to turn the .TM into a package.
    I'm using 8.6.11 on win7x64 -- not a tclkit. Putting the .TM and the
    above pkgIndex.tcl into ...\Tcl\lib\tasks successfully makes "tasks"
    able to be loaded from "package require tasks", and the Tproc procedure successfully imported.

    While .TM's may be more efficient, I prefer stuff to be in one place: \lib

    Just thought I'd share what worked for me.



    Ah, ok. I'm not supplying a pkgIndex.tcl, only the one file tasks-1.12.tm.

    Since I never install tcl (on windows), but rather have 4 or 5 tclkits
    for testing against different versions, I have no Tcl\lib directory on
    my system. When I test against linux I just use what's there. A poster
    wanted to use package require on linux, so I was trying to help him with
    that.


    Thanks for the info.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Schelte on Tue May 24 20:53:27 2022
    On 5/23/2022 2:37 AM, Schelte wrote:
    On 22/05/2022 09:07, et4 wrote:
    On 5/21/2022 8:26 AM, saitology9@gmail.com wrote:


    BTW, perhaps you could package-enable it by adding a "package provide
    Tasks" or something similar in your code.


    Anyway, it's easy enough to tack on to the end of the file, so I will
    do  > it - thanks.
    It's unnecessary. And the way you did it, by including the version
    number, it became a maintenance burden. When the version number number changes, you now have to remember to update it in two places. I suggest
    to remove it again. I never include a [package provide] command in my
    modules and they work fine.


    Schelte.

    Apologies, I also confused posters, both starting with S. I use
    Thunderbird on my desktop and google groups on my tablet. The latter
    hides previous responses by default.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Niehren@21:1/5 to All on Thu May 26 21:10:04 2022
    Hi,

    would it be possible to post an network client/server code using tasks ?

    best regards
    Michael

    et4 wrote:

    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl Programming Language" by Ashok Nadkarni, Tasks can take an independent procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large) fibonacci numbers 3-5 times faster than if done sequentially when run on
    a multi-core cpu:

    (example derived from Ashok's Promises blog)

    #----------------------------------------
    source tasks-1.12.tm
    namespace import tasks::*

    Tproc fibsize {number} {
    set fibnum [math::fibonacci $number]
    string length $fibnum
    } -tasks 5 [list {-package require math} ]

    tgroup fibsize -run 100000 100100 100200 100300 100400

    parray fibsize rvar,*
    #----------------------------------------

    Here, tgroup runs the 5 tasks (threads) concurrently and delivers the
    results to the array fibsize. [parray] then outputs the results.

    Tasks include several development tools including a handy 1 line Tk
    console and optionally one Tk window per task. It can send the same
    command to each singly or with patterns, to all or a specific group
    using task names.

    Note: a bug was discovered that can cause Tcl/Tk to crash in linux
    systems when running Tk in several threads. According to the ticket, it
    has been fixed, but I don't know which version the fix will be included
    in. For now, the code does not output using Tk but rather does puts to stdout. If you want to try it anyway, search for "hack 2" and comment
    out the incr statement. Its about line 51.

    Since task globals are partitioned by an interpreter, they are like
    namespace variables, and very easy to use. Included are list tools for
    global scalars, arrays, and a widget tree browser. Multiple monitors are
    a must.

    Tasks are source-able pure tcl. The wiki page at

    https://wiki.tcl-lang.org/page/Tasks

    provides all the documentation, examples and YouTube links to videos
    with intros and in-depth code walk-throughs to get you going with Tasks.

    The source is at GitHub at

    https://github.com/rocketship88/Tasks.git

    with a single-file tcl module named tasks-1.12.tm that can be sourced or
    if placed in an appropriate module folder loaded via package require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Michael Niehren on Thu May 26 15:08:31 2022
    On 5/26/2022 12:10 PM, Michael Niehren wrote:
    Hi,

    would it be possible to post an network client/server code using tasks ?

    best regards
    Michael

    et4 wrote:

    Announcing Tasks 1.12 an easy way to use Tcl threads.

    Tasks are an approach to writing multi-threaded script code using the
    powerful and dynamic Tcl/Tk programming language.

    Based on techniques and code from the highly acclaimed book "The Tcl
    Programming Language" by Ashok Nadkarni, Tasks can take an independent
    procedure and transform it into a multi-threaded server. It is
    especially useful for compute intensive math functions that need to be
    called several times.

    The Tasks proc-like arglist approach considerably reduces the need to
    learn new concepts. If you've wanted to dive into the Tcl threads
    package but haven't had the time to study the manual, then Tasks might
    be just the ticket for you.

    Tasks provide [Tproc] an extension to the proc command. In the below
    example a Tproc can compute the number of digits of 5 (rather large)
    fibonacci numbers 3-5 times faster than if done sequentially when run on
    a multi-core cpu:

    (example derived from Ashok's Promises blog)

    #----------------------------------------
    source tasks-1.12.tm
    namespace import tasks::*

    Tproc fibsize {number} {
    set fibnum [math::fibonacci $number]
    string length $fibnum
    } -tasks 5 [list {-package require math} ]

    tgroup fibsize -run 100000 100100 100200 100300 100400

    parray fibsize rvar,*
    #----------------------------------------

    Here, tgroup runs the 5 tasks (threads) concurrently and delivers the
    results to the array fibsize. [parray] then outputs the results.

    Tasks include several development tools including a handy 1 line Tk
    console and optionally one Tk window per task. It can send the same
    command to each singly or with patterns, to all or a specific group
    using task names.

    Note: a bug was discovered that can cause Tcl/Tk to crash in linux
    systems when running Tk in several threads. According to the ticket, it
    has been fixed, but I don't know which version the fix will be included
    in. For now, the code does not output using Tk but rather does puts to
    stdout. If you want to try it anyway, search for "hack 2" and comment
    out the incr statement. Its about line 51.

    Since task globals are partitioned by an interpreter, they are like
    namespace variables, and very easy to use. Included are list tools for
    global scalars, arrays, and a widget tree browser. Multiple monitors are
    a must.

    Tasks are source-able pure tcl. The wiki page at

    https://wiki.tcl-lang.org/page/Tasks

    provides all the documentation, examples and YouTube links to videos
    with intros and in-depth code walk-throughs to get you going with Tasks.

    The source is at GitHub at

    https://github.com/rocketship88/Tasks.git

    with a single-file tcl module named tasks-1.12.tm that can be sourced or
    if placed in an appropriate module folder loaded via package require.

    Since CPU core counts are on the rise, Tcl Tasks can gently ease one
    into concurrent programming to better utilize these new machines.


    I'm afraid the answer to your question would have to be, it depends on
    what you are trying to do.

    I would suggest that you get Ashok's book "The Tcl Programming Language"
    and look at chapter 22, and in particular 22.8 on threads and i/o
    channels. The bottom of page 569 discusses the transfer of socket
    channels, which I suspect any multi-threaded server (and I'm guessing
    that's what you want to build) would need to do.

    I would also suggest you post a new conversation and talk about network
    servers and threads and supply some detail, otherwise you'll get the
    same, "it depends" answer.

    Tasks are just threads with a different front end. Each task is a thread
    with a thread ID. Tasks are best when you have a small heavy compute
    function that you need to call many times and so want to use multiple
    cpu cores/threads. But underneath, they are just threads.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Niehren@21:1/5 to All on Tue May 31 07:51:34 2022
    Hi et,

    many thanks for you client/server code sample with tasks, that's what i was looking for. I will try it out to understand the usage.

    Michael

    et4 wrote:

    On 5/26/2022 12:10 PM, Michael Niehren wrote:
    Hi,

    would it be possible to post an network client/server code using tasks
    ?

    best regards
    Michael


    I believe I mistook your request for a question. I've uploaded to the
    wiki page a client/server network example:

    https://wiki.tcl-lang.org/page/Tasks


    It's the last example on the wiki page.

    There are 2 code blocks, one for each side. I tested it on windows and
    linux but the first line of the server needs to be changed to point to
    the path/to/ folder on either system of the tasks module location. The
    very latest is at github, see the link in the first post here.

    It is an echo/string-reverse server adapted from Ashok's example in his
    book. The client can send any number of lines and it will send them back
    over the channel string reversed.

    As configured, there's a 10 second timeout if the client side leaves the socket open w/o sending anything new. It is set for 10 server tasks, and
    0 time for simulated work (configurable at the top).

    Each connection sends a progressively longer string of xyz's. The client
    will run 500k connections if left running for many hours. Might need to control-c clients to kill them on linux. On windows, it opens a console.

    Run both sides from a wish, server first or client(s) will abort. Can
    then run multiple clients from separate terminal windows on same machine
    or other machines.

    The client presents a small window with an error count, progress count,
    and pause checkbox. Client checks return for expected results. The
    server also runs the task monitor task. Lower the refresh to .5 for best results. The result(s) column has the connection info; the user column
    has the size and 20 chars of data. It's sending rather large lines >150k each. Can also monitor with wire-shark.

    et

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Michael Niehren on Mon May 30 22:24:03 2022
    On 5/26/2022 12:10 PM, Michael Niehren wrote:
    Hi,

    would it be possible to post an network client/server code using tasks ?

    best regards
    Michael


    I believe I mistook your request for a question. I've uploaded to the
    wiki page a client/server network example:

    https://wiki.tcl-lang.org/page/Tasks


    It's the last example on the wiki page.

    There are 2 code blocks, one for each side. I tested it on windows and
    linux but the first line of the server needs to be changed to point to
    the path/to/ folder on either system of the tasks module location. The
    very latest is at github, see the link in the first post here.

    It is an echo/string-reverse server adapted from Ashok's example in his
    book. The client can send any number of lines and it will send them back
    over the channel string reversed.

    As configured, there's a 10 second timeout if the client side leaves the
    socket open w/o sending anything new. It is set for 10 server tasks, and
    0 time for simulated work (configurable at the top).

    Each connection sends a progressively longer string of xyz's. The client
    will run 500k connections if left running for many hours. Might need to control-c clients to kill them on linux. On windows, it opens a console.

    Run both sides from a wish, server first or client(s) will abort. Can
    then run multiple clients from separate terminal windows on same machine
    or other machines.

    The client presents a small window with an error count, progress count,
    and pause checkbox. Client checks return for expected results. The
    server also runs the task monitor task. Lower the refresh to .5 for best results. The result(s) column has the connection info; the user column
    has the size and 20 chars of data. It's sending rather large lines >150k
    each. Can also monitor with wire-shark.

    et

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Michael Niehren on Tue May 31 15:00:50 2022
    On 5/30/2022 10:51 PM, Michael Niehren wrote:
    Hi et,

    many thanks for you client/server code sample with tasks, that's what i was looking for. I will try it out to understand the usage.

    Michael

    et4 wrote:

    On 5/26/2022 12:10 PM, Michael Niehren wrote:
    > Hi,
    >
    > would it be possible to post an network client/server code using tasks >> > ?
    >
    > best regards
    > Michael
    >

    I believe I mistook your request for a question. I've uploaded to the
    wiki page a client/server network example:

    https://wiki.tcl-lang.org/page/Tasks


    It's the last example on the wiki page.

    There are 2 code blocks, one for each side. I tested it on windows and
    linux but the first line of the server needs to be changed to point to
    the path/to/ folder on either system of the tasks module location. The
    very latest is at github, see the link in the first post here.

    It is an echo/string-reverse server adapted from Ashok's example in his
    book. The client can send any number of lines and it will send them back
    over the channel string reversed.

    As configured, there's a 10 second timeout if the client side leaves the
    socket open w/o sending anything new. It is set for 10 server tasks, and
    0 time for simulated work (configurable at the top).

    Each connection sends a progressively longer string of xyz's. The client
    will run 500k connections if left running for many hours. Might need to
    control-c clients to kill them on linux. On windows, it opens a console.

    Run both sides from a wish, server first or client(s) will abort. Can
    then run multiple clients from separate terminal windows on same machine
    or other machines.

    The client presents a small window with an error count, progress count,
    and pause checkbox. Client checks return for expected results. The
    server also runs the task monitor task. Lower the refresh to .5 for best
    results. The result(s) column has the connection info; the user column
    has the size and 20 chars of data. It's sending rather large lines >150k
    each. Can also monitor with wire-shark.

    et


    Thanks for looking at it. I will be updating it in a while, since there
    is a minor problem. When you kill off a client, it can cause the [gets]
    in the event callback (on_read) to throw an error. I've been able to
    force this to happen, but it's difficult.

    Appears to be a timing issue where the socket is closed between having
    become readable, and just before the event callback can call the gets.

    The fix is a catch around it, a close channel, and return from the
    event. I'm testing it now on windows and linux.

    But it did survive my overnight test for resource leaks. I ran the
    server on a linux VM and 4 clients, 2 from within the VM on linux, and 2
    from outside windows 10 machines. Over 2 million connections and neither windows nor linux crashed :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)