Browse Source

repl debug, updated shellfilter,shellthread,punk::netbox

master
Julian Noble 1 week ago
parent
commit
ce9c44c3c3
  1. 1
      src/bootsupport/modules/punk/args-0.2.1.tm
  2. 20
      src/bootsupport/modules/punk/console-0.1.1.tm
  3. 2
      src/bootsupport/modules/punk/repl-0.1.2.tm
  4. 18
      src/bootsupport/modules/shellfilter-0.2.1.tm
  5. 44
      src/bootsupport/modules/shellthread-1.6.2.tm
  6. 9489
      src/bootsupport/modules/tomlish-1.1.8.tm
  7. 82
      src/modules/punk/netbox-999999.0a1.0.tm
  8. 2
      src/modules/punk/repl-999999.0a1.0.tm
  9. 1
      src/modules/shellfilter-999999.0a1.0.tm
  10. 2
      src/modules/shellthread-999999.0a1.0.tm
  11. 1
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm
  12. 20
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  13. 2
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repl-0.1.2.tm
  14. 18
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellfilter-0.2.1.tm
  15. 44
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellthread-1.6.2.tm
  16. 9489
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/tomlish-1.1.8.tm
  17. 1
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm
  18. 20
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  19. 2
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repl-0.1.2.tm
  20. 18
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellfilter-0.2.1.tm
  21. 44
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellthread-1.6.2.tm
  22. 9489
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/tomlish-1.1.8.tm

1
src/bootsupport/modules/punk/args-0.2.1.tm

@ -4897,7 +4897,6 @@ tcl::namespace::eval punk::args {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@dynamic
@id -id ::punk::args::usage @id -id ::punk::args::usage
@cmd -name punk::args::usage -help\ @cmd -name punk::args::usage -help\
"Return usage information for a command identified by an id. "Return usage information for a command identified by an id.

20
src/bootsupport/modules/punk/console-0.1.1.tm

@ -515,8 +515,18 @@ namespace eval punk::console {
} }
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd -icanon -echo -isig
}
default {
exec {*}$sttycmd raw -echo <@$channel exec {*}$sttycmd raw -echo <@$channel
}
}
catch {
tsv::set console is_raw 1 tsv::set console is_raw 1
}
return [dict create previous [set previous_stty_state_$channel]] return [dict create previous [set previous_stty_state_$channel]]
} }
proc disableRaw {{channel stdin}} { proc disableRaw {{channel stdin}} {
@ -529,8 +539,18 @@ namespace eval punk::console {
tsv::set console is_raw 0 tsv::set console is_raw 0
return restored return restored
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd icanon echo isig
}
default {
exec {*}$sttycmd -raw echo <@$channel exec {*}$sttycmd -raw echo <@$channel
}
}
catch {
tsv::set console is_raw 0 tsv::set console is_raw 0
}
return done return done
} }
} }

2
src/bootsupport/modules/punk/repl-0.1.2.tm

@ -2854,7 +2854,7 @@ namespace eval repl {
if {$libunknown ne ""} { if {$libunknown ne ""} {
uplevel 1 [list source $libunknown] uplevel 1 [list source $libunknown]
if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} { if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} {
puts "repl::init problem - error initialising punk::libunknown\n$errM" puts "repl::init problem - error initialising punk::libunknown\n from '$libunknown'\n err $errM"
} }
#package require punk::lib #package require punk::lib
#puts [punk::libunknown::package_query snit] #puts [punk::libunknown::package_query snit]

18
src/bootsupport/modules/shellfilter-0.2.1.tm

@ -28,6 +28,9 @@ tcl::namespace::eval shellfilter::log {
variable is_enabled variable is_enabled
set is_enabled 1 set is_enabled 1
#'tag' is an identifier for the log source. #'tag' is an identifier for the log source.
#(well.. really it's a common *target* of file and/or syslog host:port which can be written to from any thread that uses the tag)
#the terminology here is kinda ratshit.
# each tag will use it's own thread to write to the configured log target # each tag will use it's own thread to write to the configured log target
proc ::shellfilter::log::open {tag {settingsdict {}}} { proc ::shellfilter::log::open {tag {settingsdict {}}} {
upvar ::shellfilter::sources sourcelist upvar ::shellfilter::sources sourcelist
@ -43,7 +46,7 @@ tcl::namespace::eval shellfilter::log {
lappend sourcelist $tag lappend sourcelist $tag
} }
#note new_worker #review new_worker/assign_worker?
set worker_tid [shellthread::manager::new_worker $tag $settingsdict] set worker_tid [shellthread::manager::new_worker $tag $settingsdict]
#puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid" #puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid"
return $worker_tid return $worker_tid
@ -138,6 +141,7 @@ namespace eval shellfilter::pipe {
chan configure $worker_chan -buffering [dict get $settingsdict -buffering] chan configure $worker_chan -buffering [dict get $settingsdict -buffering]
chan configure $program_chan -buffering [dict get $settingsdict -buffering] chan configure $program_chan -buffering [dict get $settingsdict -buffering]
#review
chan configure $program_chan -blocking 0 chan configure $program_chan -blocking 0
chan configure $worker_chan -blocking 0 chan configure $worker_chan -blocking 0
set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict] set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict]
@ -2639,7 +2643,12 @@ namespace eval shellfilter {
::shellfilter::log::write $debugname " waitvar '$waitvar'" ::shellfilter::log::write $debugname " waitvar '$waitvar'"
} }
lassign [chan pipe] rderr wrerr lassign [chan pipe] rderr wrerr
chan configure $wrerr -blocking 0
#---------------
#JMN 2025
# e.g cannot run ansible cmdline tools if non-blocking
#chan configure $wrerr -blocking 0
#------------------
set custom_stderr "" set custom_stderr ""
set lastitem [lindex $commandlist end] set lastitem [lindex $commandlist end]
@ -2824,7 +2833,8 @@ namespace eval shellfilter {
#chan configure $inchan -buffering none -blocking 1 ;#test #chan configure $inchan -buffering none -blocking 1 ;#test
chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok #chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok
chan configure $inchan -buffering $inbuffering
chan configure $errchan -buffering $errbuffering chan configure $errchan -buffering $errbuffering
@ -3176,6 +3186,8 @@ namespace eval shellfilter {
#set newbytes [encoding convertto utf-16 $stringrep] #set newbytes [encoding convertto utf-16 $stringrep]
#puts -nonewline $outchan $newbytes #puts -nonewline $outchan $newbytes
puts -nonewline $outchan $outchunk puts -nonewline $outchan $outchunk
#jmn test 2025
flush $outchan
} }
} }

44
src/bootsupport/modules/shellthread-1.6.2.tm

@ -21,6 +21,8 @@ namespace eval shellthread {
namespace eval shellthread::worker { namespace eval shellthread::worker {
variable settings variable settings
variable settings_defaults
set settings_defaults [list -raw 0 -file "" -syslog "" -direction out] ;#also used for reset when worker returned to free thread list
variable sysloghost_port variable sysloghost_port
variable sock variable sock
variable logfile "" variable logfile ""
@ -48,6 +50,7 @@ namespace eval shellthread::worker {
variable sysloghost_port variable sysloghost_port
variable logfile variable logfile
variable settings variable settings
variable settings_defaults
interp bgerror {} shellthread::worker::bgerror interp bgerror {} shellthread::worker::bgerror
#package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads. #package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads.
variable client_ids variable client_ids
@ -55,8 +58,7 @@ namespace eval shellthread::worker {
lappend client_ids $tidclient lappend client_ids $tidclient
set ts_start_micros $start_m set ts_start_micros $start_m
set defaults [list -raw 0 -file "" -syslog "" -direction out] set settings [dict merge $settings_defaults $settingsdict]
set settings [dict merge $defaults $settingsdict]
set syslog [dict get $settings -syslog] set syslog [dict get $settings -syslog]
if {[string length $syslog]} { if {[string length $syslog]} {
@ -111,7 +113,9 @@ namespace eval shellthread::worker {
error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end" error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end"
} }
set inpipe $readchan set inpipe $readchan
chan configure $readchan -blocking 0
#JMN 2025
#chan configure $readchan -blocking 0
set waitvar ::shellthread::worker::wait($inpipe,[clock micros]) set waitvar ::shellthread::worker::wait($inpipe,[clock micros])
#tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan #tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan
@ -486,9 +490,24 @@ namespace eval shellthread::manager {
set winfo [dict get $workers $sourcetag] set winfo [dict get $workers $sourcetag]
if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} { if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} {
# add our client-info to existing worker thread # add our client-info to existing worker thread
set existing_settings [get_tag_config $sourcetag]
if {$settingsdict eq $existing_settings} {
#same settings - share the worker
dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid]
} elseif {$existing_settings eq {-raw 0 -file {} -syslog {} -direction out}} {
#review - magic dict seems brittle - shouldn't hard code here.???
dict lappend winfo list_client_tids $tidclient dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid] return [dict get $winfo tid]
} else {
set emsg "shellthread::manager::new_worker error: tag $sourcetag already has a worker with a different configuration\n"
append emsg "existing: $existing_settings\n"
append emsg "attempted: $settingsdict\n"
append emsg "workers info: $winfo"
error $emsg
}
} }
} }
@ -508,7 +527,9 @@ namespace eval shellthread::manager {
if {[llength $free_threads]} { if {[llength $free_threads]} {
#todo - re-use from tail - as most likely to have been doing similar work?? review #todo - re-use from tail - as most likely to have been doing similar work?? review
set free_threads [lassign $free_threads tidworker] #set free_threads [lassign $free_threads tidworker]
set tidworker [lpop free_threads 0]
#todo - keep track of real ts_start of free threads... kill when too old #todo - keep track of real ts_start of free threads... kill when too old
set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]] set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]]
#puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag" #puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag"
@ -641,7 +662,7 @@ namespace eval shellthread::manager {
proc unsubscribe {sourcetaglist} { proc unsubscribe {sourcetaglist} {
variable workers variable workers
#workers structure example: #workers structure example:
#[list sourcetag1 [list tid <tidworker> list_client_tids <clients>] ts_start <ts_start> ts_end_list {}] #[list sourcetag1 [list tid <tidworker> list_client_tids <clients> ts_start <ts_start> ts_end_list {} workertype message|pipe]]
variable free_threads variable free_threads
set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread
@ -684,6 +705,9 @@ namespace eval shellthread::manager {
foreach workertid $subscriberless_workers { foreach workertid $subscriberless_workers {
if {$workertid ni $shuttingdown_workers} { if {$workertid ni $shuttingdown_workers} {
if {$workertid ni $free_threads && $workertid ne "noop"} { if {$workertid ni $free_threads && $workertid ne "noop"} {
#JMN
thread::send $workertid {set ::shellthread::worker::settings $::shellthread::worker::settings_defaults}
#todo - log freeing up of thread
lappend free_threads $workertid lappend free_threads $workertid
} }
} }
@ -704,6 +728,16 @@ namespace eval shellthread::manager {
return $taginfo_list return $taginfo_list
} }
proc get_tag_config {tag} {
#review
variable workers
if {![dict exists $workers $tag]} {
error "shellthread::manager::get_tag_config error no existing tag $tag"
}
set workertid [dict get $workers $tag tid]
set conf [thread::send $workertid {set ::shellthread::worker::settings}]
}
#finalisation #finalisation
proc shutdown_free_threads {{timeout 2500}} { proc shutdown_free_threads {{timeout 2500}} {
variable free_threads variable free_threads

9489
src/bootsupport/modules/tomlish-1.1.8.tm

File diff suppressed because it is too large Load Diff

82
src/modules/punk/netbox-999999.0a1.0.tm

@ -2264,6 +2264,8 @@ tcl::namespace::eval punk::netbox::ipam {
{ {
-family -family
-parent -parent
#need later netbox than 3.2.7 for -parent__n?
-parent__n
-address -address
-mask_length -mask_length
-vrf_id -vrf_id
@ -2514,6 +2516,10 @@ tcl::namespace::eval punk::netbox::virtualization {
variable PUNKARGS variable PUNKARGS
variable DYN_CONTEXTNAMES variable DYN_CONTEXTNAMES
set DYN_CONTEXTNAMES {${[punk::netbox::api_context_names]}} set DYN_CONTEXTNAMES {${[punk::netbox::api_context_names]}}
}
namespace eval argdoc {
lappend PUNKARGS [list\ lappend PUNKARGS [list\
{ {
@dynamic @dynamic
@ -2593,7 +2599,7 @@ tcl::namespace::eval punk::netbox::virtualization {
-name -name
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_name_filter_help}} -NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_name_filter_help}}
-cluster -type string -cluster -type string
-cluster_n -type string -cluster__n -type string
-vcpus -type integer -vcpus -type integer
-VCPUS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_number_filter_help}} -VCPUS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_number_filter_help}}
-memory -type integer -help\ -memory -type integer -help\
@ -2787,6 +2793,80 @@ tcl::namespace::eval punk::netbox::virtualization {
} }
::punk::netbox::system::make_rest_func_async ::punk::netbox::virtualization::virtual-machines_delete api/virtualization/virtual-machines/{id}/ -verb delete -body none ::punk::netbox::system::make_rest_func_async ::punk::netbox::virtualization::virtual-machines_delete api/virtualization/virtual-machines/{id}/ -verb delete -body none
namespace eval argdoc {
lappend PUNKARGS [list\
{
@dynamic
@id -id ::punk::netbox::virtualization::interfaces_list
@cmd -name punk::netbox::virtualization::interfaces_list -help\
"virtualization_interfaces_list
GET request for endpoint /virtualization/interfaces/"
@leaders -min 1 -max 1
apicontextid -help\
"The name of the stored api context to use.
A contextid can be created in-memory using
api_context_create, or loaded from a .toml
file using api_context_load."\
-choices {${$DYN_CONTEXTNAMES}}
@opts
-id -type integer
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_number_filter_help}}
-name
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_name_filter_help}}
-enabled -type string
-mtu -type string
-MTU_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_number_filter_help}}
-mac_address -type string
-MAC_ADDRESS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_string_filter_help}}
-description -type string
-DESCRIPTION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -unindentedfields {-help} -help {${$::punk::netbox::argdoc::_name_filter_help}}
}\
[set ::punk::netbox::argdoc::_create_update_options]\
{
-q
-tag -multiple true
-tag__n -multiple true
}\
[set ::punk::netbox::argdoc::_tenant_options]\
[set ::punk::netbox::argdoc::_contact_options]\
{
-status
-status__n
-cluster -type string
-cluster__n -type string
-cluster_id -type integer
-cluster_id__n -type integer
-virtual_machine -type string
-virtual_machine__n -type string
-virtual_machine_id -type integer
-virtual_machine_id__n -type integer
}\
[set ::punk::netbox::argdoc::_region_options]\
[set ::punk::netbox::argdoc::_site_options]\
{
-vrf_id -type integer
-vrf_id__n -type integer
-vrf -type string
-vrf__n -type string
-parent_id -type integer
-parent_id__n -type integer
-bridge_id -type integer
-bridge_id__n -type integer
}\
[set ::punk::netbox::argdoc::_group_options]\
[set ::punk::netbox::argdoc::_role_options]\
{
}\
[set ::punk::netbox::argdoc::_page_options]\
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\
{
@values -min 0 -max 0
}]
}
::punk::netbox::system::make_rest_func_async ::punk::netbox::virtualization::interfaces_list api/virtualization/interfaces/ -verb get -body none
} }
tcl::namespace::eval punk::netbox::extras { tcl::namespace::eval punk::netbox::extras {

2
src/modules/punk/repl-999999.0a1.0.tm

@ -2854,7 +2854,7 @@ namespace eval repl {
if {$libunknown ne ""} { if {$libunknown ne ""} {
uplevel 1 [list source $libunknown] uplevel 1 [list source $libunknown]
if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} { if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} {
puts "repl::init problem - error initialising punk::libunknown\n$errM" puts "repl::init problem - error initialising punk::libunknown\n from '$libunknown'\n err $errM"
} }
#package require punk::lib #package require punk::lib
#puts [punk::libunknown::package_query snit] #puts [punk::libunknown::package_query snit]

1
src/modules/shellfilter-999999.0a1.0.tm

@ -141,6 +141,7 @@ namespace eval shellfilter::pipe {
chan configure $worker_chan -buffering [dict get $settingsdict -buffering] chan configure $worker_chan -buffering [dict get $settingsdict -buffering]
chan configure $program_chan -buffering [dict get $settingsdict -buffering] chan configure $program_chan -buffering [dict get $settingsdict -buffering]
#review
chan configure $program_chan -blocking 0 chan configure $program_chan -blocking 0
chan configure $worker_chan -blocking 0 chan configure $worker_chan -blocking 0
set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict] set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict]

2
src/modules/shellthread-999999.0a1.0.tm

@ -497,7 +497,7 @@ namespace eval shellthread::manager {
dict set workers $sourcetag $winfo ;#writeback dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid] return [dict get $winfo tid]
} elseif {$existing_settings eq {-raw 0 -file {} -syslog {} -direction out}} { } elseif {$existing_settings eq {-raw 0 -file {} -syslog {} -direction out}} {
#review - magic dict is default - shouldn't hard code here. #review - magic dict seems brittle - shouldn't hard code here.???
dict lappend winfo list_client_tids $tidclient dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid] return [dict get $winfo tid]

1
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm

@ -4897,7 +4897,6 @@ tcl::namespace::eval punk::args {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@dynamic
@id -id ::punk::args::usage @id -id ::punk::args::usage
@cmd -name punk::args::usage -help\ @cmd -name punk::args::usage -help\
"Return usage information for a command identified by an id. "Return usage information for a command identified by an id.

20
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -515,8 +515,18 @@ namespace eval punk::console {
} }
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd -icanon -echo -isig
}
default {
exec {*}$sttycmd raw -echo <@$channel exec {*}$sttycmd raw -echo <@$channel
}
}
catch {
tsv::set console is_raw 1 tsv::set console is_raw 1
}
return [dict create previous [set previous_stty_state_$channel]] return [dict create previous [set previous_stty_state_$channel]]
} }
proc disableRaw {{channel stdin}} { proc disableRaw {{channel stdin}} {
@ -529,8 +539,18 @@ namespace eval punk::console {
tsv::set console is_raw 0 tsv::set console is_raw 0
return restored return restored
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd icanon echo isig
}
default {
exec {*}$sttycmd -raw echo <@$channel exec {*}$sttycmd -raw echo <@$channel
}
}
catch {
tsv::set console is_raw 0 tsv::set console is_raw 0
}
return done return done
} }
} }

2
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repl-0.1.2.tm

@ -2854,7 +2854,7 @@ namespace eval repl {
if {$libunknown ne ""} { if {$libunknown ne ""} {
uplevel 1 [list source $libunknown] uplevel 1 [list source $libunknown]
if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} { if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} {
puts "repl::init problem - error initialising punk::libunknown\n$errM" puts "repl::init problem - error initialising punk::libunknown\n from '$libunknown'\n err $errM"
} }
#package require punk::lib #package require punk::lib
#puts [punk::libunknown::package_query snit] #puts [punk::libunknown::package_query snit]

18
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellfilter-0.2.1.tm

@ -28,6 +28,9 @@ tcl::namespace::eval shellfilter::log {
variable is_enabled variable is_enabled
set is_enabled 1 set is_enabled 1
#'tag' is an identifier for the log source. #'tag' is an identifier for the log source.
#(well.. really it's a common *target* of file and/or syslog host:port which can be written to from any thread that uses the tag)
#the terminology here is kinda ratshit.
# each tag will use it's own thread to write to the configured log target # each tag will use it's own thread to write to the configured log target
proc ::shellfilter::log::open {tag {settingsdict {}}} { proc ::shellfilter::log::open {tag {settingsdict {}}} {
upvar ::shellfilter::sources sourcelist upvar ::shellfilter::sources sourcelist
@ -43,7 +46,7 @@ tcl::namespace::eval shellfilter::log {
lappend sourcelist $tag lappend sourcelist $tag
} }
#note new_worker #review new_worker/assign_worker?
set worker_tid [shellthread::manager::new_worker $tag $settingsdict] set worker_tid [shellthread::manager::new_worker $tag $settingsdict]
#puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid" #puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid"
return $worker_tid return $worker_tid
@ -138,6 +141,7 @@ namespace eval shellfilter::pipe {
chan configure $worker_chan -buffering [dict get $settingsdict -buffering] chan configure $worker_chan -buffering [dict get $settingsdict -buffering]
chan configure $program_chan -buffering [dict get $settingsdict -buffering] chan configure $program_chan -buffering [dict get $settingsdict -buffering]
#review
chan configure $program_chan -blocking 0 chan configure $program_chan -blocking 0
chan configure $worker_chan -blocking 0 chan configure $worker_chan -blocking 0
set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict] set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict]
@ -2639,7 +2643,12 @@ namespace eval shellfilter {
::shellfilter::log::write $debugname " waitvar '$waitvar'" ::shellfilter::log::write $debugname " waitvar '$waitvar'"
} }
lassign [chan pipe] rderr wrerr lassign [chan pipe] rderr wrerr
chan configure $wrerr -blocking 0
#---------------
#JMN 2025
# e.g cannot run ansible cmdline tools if non-blocking
#chan configure $wrerr -blocking 0
#------------------
set custom_stderr "" set custom_stderr ""
set lastitem [lindex $commandlist end] set lastitem [lindex $commandlist end]
@ -2824,7 +2833,8 @@ namespace eval shellfilter {
#chan configure $inchan -buffering none -blocking 1 ;#test #chan configure $inchan -buffering none -blocking 1 ;#test
chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok #chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok
chan configure $inchan -buffering $inbuffering
chan configure $errchan -buffering $errbuffering chan configure $errchan -buffering $errbuffering
@ -3176,6 +3186,8 @@ namespace eval shellfilter {
#set newbytes [encoding convertto utf-16 $stringrep] #set newbytes [encoding convertto utf-16 $stringrep]
#puts -nonewline $outchan $newbytes #puts -nonewline $outchan $newbytes
puts -nonewline $outchan $outchunk puts -nonewline $outchan $outchunk
#jmn test 2025
flush $outchan
} }
} }

44
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellthread-1.6.2.tm

@ -21,6 +21,8 @@ namespace eval shellthread {
namespace eval shellthread::worker { namespace eval shellthread::worker {
variable settings variable settings
variable settings_defaults
set settings_defaults [list -raw 0 -file "" -syslog "" -direction out] ;#also used for reset when worker returned to free thread list
variable sysloghost_port variable sysloghost_port
variable sock variable sock
variable logfile "" variable logfile ""
@ -48,6 +50,7 @@ namespace eval shellthread::worker {
variable sysloghost_port variable sysloghost_port
variable logfile variable logfile
variable settings variable settings
variable settings_defaults
interp bgerror {} shellthread::worker::bgerror interp bgerror {} shellthread::worker::bgerror
#package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads. #package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads.
variable client_ids variable client_ids
@ -55,8 +58,7 @@ namespace eval shellthread::worker {
lappend client_ids $tidclient lappend client_ids $tidclient
set ts_start_micros $start_m set ts_start_micros $start_m
set defaults [list -raw 0 -file "" -syslog "" -direction out] set settings [dict merge $settings_defaults $settingsdict]
set settings [dict merge $defaults $settingsdict]
set syslog [dict get $settings -syslog] set syslog [dict get $settings -syslog]
if {[string length $syslog]} { if {[string length $syslog]} {
@ -111,7 +113,9 @@ namespace eval shellthread::worker {
error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end" error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end"
} }
set inpipe $readchan set inpipe $readchan
chan configure $readchan -blocking 0
#JMN 2025
#chan configure $readchan -blocking 0
set waitvar ::shellthread::worker::wait($inpipe,[clock micros]) set waitvar ::shellthread::worker::wait($inpipe,[clock micros])
#tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan #tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan
@ -486,9 +490,24 @@ namespace eval shellthread::manager {
set winfo [dict get $workers $sourcetag] set winfo [dict get $workers $sourcetag]
if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} { if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} {
# add our client-info to existing worker thread # add our client-info to existing worker thread
set existing_settings [get_tag_config $sourcetag]
if {$settingsdict eq $existing_settings} {
#same settings - share the worker
dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid]
} elseif {$existing_settings eq {-raw 0 -file {} -syslog {} -direction out}} {
#review - magic dict seems brittle - shouldn't hard code here.???
dict lappend winfo list_client_tids $tidclient dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid] return [dict get $winfo tid]
} else {
set emsg "shellthread::manager::new_worker error: tag $sourcetag already has a worker with a different configuration\n"
append emsg "existing: $existing_settings\n"
append emsg "attempted: $settingsdict\n"
append emsg "workers info: $winfo"
error $emsg
}
} }
} }
@ -508,7 +527,9 @@ namespace eval shellthread::manager {
if {[llength $free_threads]} { if {[llength $free_threads]} {
#todo - re-use from tail - as most likely to have been doing similar work?? review #todo - re-use from tail - as most likely to have been doing similar work?? review
set free_threads [lassign $free_threads tidworker] #set free_threads [lassign $free_threads tidworker]
set tidworker [lpop free_threads 0]
#todo - keep track of real ts_start of free threads... kill when too old #todo - keep track of real ts_start of free threads... kill when too old
set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]] set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]]
#puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag" #puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag"
@ -641,7 +662,7 @@ namespace eval shellthread::manager {
proc unsubscribe {sourcetaglist} { proc unsubscribe {sourcetaglist} {
variable workers variable workers
#workers structure example: #workers structure example:
#[list sourcetag1 [list tid <tidworker> list_client_tids <clients>] ts_start <ts_start> ts_end_list {}] #[list sourcetag1 [list tid <tidworker> list_client_tids <clients> ts_start <ts_start> ts_end_list {} workertype message|pipe]]
variable free_threads variable free_threads
set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread
@ -684,6 +705,9 @@ namespace eval shellthread::manager {
foreach workertid $subscriberless_workers { foreach workertid $subscriberless_workers {
if {$workertid ni $shuttingdown_workers} { if {$workertid ni $shuttingdown_workers} {
if {$workertid ni $free_threads && $workertid ne "noop"} { if {$workertid ni $free_threads && $workertid ne "noop"} {
#JMN
thread::send $workertid {set ::shellthread::worker::settings $::shellthread::worker::settings_defaults}
#todo - log freeing up of thread
lappend free_threads $workertid lappend free_threads $workertid
} }
} }
@ -704,6 +728,16 @@ namespace eval shellthread::manager {
return $taginfo_list return $taginfo_list
} }
proc get_tag_config {tag} {
#review
variable workers
if {![dict exists $workers $tag]} {
error "shellthread::manager::get_tag_config error no existing tag $tag"
}
set workertid [dict get $workers $tag tid]
set conf [thread::send $workertid {set ::shellthread::worker::settings}]
}
#finalisation #finalisation
proc shutdown_free_threads {{timeout 2500}} { proc shutdown_free_threads {{timeout 2500}} {
variable free_threads variable free_threads

9489
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/tomlish-1.1.8.tm

File diff suppressed because it is too large Load Diff

1
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm

@ -4897,7 +4897,6 @@ tcl::namespace::eval punk::args {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@dynamic
@id -id ::punk::args::usage @id -id ::punk::args::usage
@cmd -name punk::args::usage -help\ @cmd -name punk::args::usage -help\
"Return usage information for a command identified by an id. "Return usage information for a command identified by an id.

20
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -515,8 +515,18 @@ namespace eval punk::console {
} }
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd -icanon -echo -isig
}
default {
exec {*}$sttycmd raw -echo <@$channel exec {*}$sttycmd raw -echo <@$channel
}
}
catch {
tsv::set console is_raw 1 tsv::set console is_raw 1
}
return [dict create previous [set previous_stty_state_$channel]] return [dict create previous [set previous_stty_state_$channel]]
} }
proc disableRaw {{channel stdin}} { proc disableRaw {{channel stdin}} {
@ -529,8 +539,18 @@ namespace eval punk::console {
tsv::set console is_raw 0 tsv::set console is_raw 0
return restored return restored
} }
#REVIEW
switch $channel {
stdin {
exec {*}$sttycmd icanon echo isig
}
default {
exec {*}$sttycmd -raw echo <@$channel exec {*}$sttycmd -raw echo <@$channel
}
}
catch {
tsv::set console is_raw 0 tsv::set console is_raw 0
}
return done return done
} }
} }

2
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repl-0.1.2.tm

@ -2854,7 +2854,7 @@ namespace eval repl {
if {$libunknown ne ""} { if {$libunknown ne ""} {
uplevel 1 [list source $libunknown] uplevel 1 [list source $libunknown]
if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} { if {[catch {punk::libunknown::init -caller "repl::init init_script parent interp"} errM]} {
puts "repl::init problem - error initialising punk::libunknown\n$errM" puts "repl::init problem - error initialising punk::libunknown\n from '$libunknown'\n err $errM"
} }
#package require punk::lib #package require punk::lib
#puts [punk::libunknown::package_query snit] #puts [punk::libunknown::package_query snit]

18
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellfilter-0.2.1.tm

@ -28,6 +28,9 @@ tcl::namespace::eval shellfilter::log {
variable is_enabled variable is_enabled
set is_enabled 1 set is_enabled 1
#'tag' is an identifier for the log source. #'tag' is an identifier for the log source.
#(well.. really it's a common *target* of file and/or syslog host:port which can be written to from any thread that uses the tag)
#the terminology here is kinda ratshit.
# each tag will use it's own thread to write to the configured log target # each tag will use it's own thread to write to the configured log target
proc ::shellfilter::log::open {tag {settingsdict {}}} { proc ::shellfilter::log::open {tag {settingsdict {}}} {
upvar ::shellfilter::sources sourcelist upvar ::shellfilter::sources sourcelist
@ -43,7 +46,7 @@ tcl::namespace::eval shellfilter::log {
lappend sourcelist $tag lappend sourcelist $tag
} }
#note new_worker #review new_worker/assign_worker?
set worker_tid [shellthread::manager::new_worker $tag $settingsdict] set worker_tid [shellthread::manager::new_worker $tag $settingsdict]
#puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid" #puts stderr "shellfilter::log::open this_threadid: [thread::id] tag: $tag worker_tid: $worker_tid"
return $worker_tid return $worker_tid
@ -138,6 +141,7 @@ namespace eval shellfilter::pipe {
chan configure $worker_chan -buffering [dict get $settingsdict -buffering] chan configure $worker_chan -buffering [dict get $settingsdict -buffering]
chan configure $program_chan -buffering [dict get $settingsdict -buffering] chan configure $program_chan -buffering [dict get $settingsdict -buffering]
#review
chan configure $program_chan -blocking 0 chan configure $program_chan -blocking 0
chan configure $worker_chan -blocking 0 chan configure $worker_chan -blocking 0
set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict] set worker_tid [shellthread::manager::new_worker $tag_pipename $settingsdict]
@ -2639,7 +2643,12 @@ namespace eval shellfilter {
::shellfilter::log::write $debugname " waitvar '$waitvar'" ::shellfilter::log::write $debugname " waitvar '$waitvar'"
} }
lassign [chan pipe] rderr wrerr lassign [chan pipe] rderr wrerr
chan configure $wrerr -blocking 0
#---------------
#JMN 2025
# e.g cannot run ansible cmdline tools if non-blocking
#chan configure $wrerr -blocking 0
#------------------
set custom_stderr "" set custom_stderr ""
set lastitem [lindex $commandlist end] set lastitem [lindex $commandlist end]
@ -2824,7 +2833,8 @@ namespace eval shellfilter {
#chan configure $inchan -buffering none -blocking 1 ;#test #chan configure $inchan -buffering none -blocking 1 ;#test
chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok #chan configure $inchan -buffering $inbuffering -blocking 0 ;#we are setting up a readable handler for this - so non-blocking ok
chan configure $inchan -buffering $inbuffering
chan configure $errchan -buffering $errbuffering chan configure $errchan -buffering $errbuffering
@ -3176,6 +3186,8 @@ namespace eval shellfilter {
#set newbytes [encoding convertto utf-16 $stringrep] #set newbytes [encoding convertto utf-16 $stringrep]
#puts -nonewline $outchan $newbytes #puts -nonewline $outchan $newbytes
puts -nonewline $outchan $outchunk puts -nonewline $outchan $outchunk
#jmn test 2025
flush $outchan
} }
} }

44
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellthread-1.6.2.tm

@ -21,6 +21,8 @@ namespace eval shellthread {
namespace eval shellthread::worker { namespace eval shellthread::worker {
variable settings variable settings
variable settings_defaults
set settings_defaults [list -raw 0 -file "" -syslog "" -direction out] ;#also used for reset when worker returned to free thread list
variable sysloghost_port variable sysloghost_port
variable sock variable sock
variable logfile "" variable logfile ""
@ -48,6 +50,7 @@ namespace eval shellthread::worker {
variable sysloghost_port variable sysloghost_port
variable logfile variable logfile
variable settings variable settings
variable settings_defaults
interp bgerror {} shellthread::worker::bgerror interp bgerror {} shellthread::worker::bgerror
#package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads. #package require overtype ;#overtype uses tcllib textutil, punk::char etc - currently too heavyweight in terms of loading time for use in threads.
variable client_ids variable client_ids
@ -55,8 +58,7 @@ namespace eval shellthread::worker {
lappend client_ids $tidclient lappend client_ids $tidclient
set ts_start_micros $start_m set ts_start_micros $start_m
set defaults [list -raw 0 -file "" -syslog "" -direction out] set settings [dict merge $settings_defaults $settingsdict]
set settings [dict merge $defaults $settingsdict]
set syslog [dict get $settings -syslog] set syslog [dict get $settings -syslog]
if {[string length $syslog]} { if {[string length $syslog]} {
@ -111,7 +113,9 @@ namespace eval shellthread::worker {
error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end" error "shellthread::worker::start_pipe_read - inpipe not configured. Use shellthread::manager::set_pipe_read_from_client to thread::transfer the pipe end"
} }
set inpipe $readchan set inpipe $readchan
chan configure $readchan -blocking 0
#JMN 2025
#chan configure $readchan -blocking 0
set waitvar ::shellthread::worker::wait($inpipe,[clock micros]) set waitvar ::shellthread::worker::wait($inpipe,[clock micros])
#tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan #tcl::chan::fifo2 based pipe seems slower to establish events upon than Memchan
@ -486,9 +490,24 @@ namespace eval shellthread::manager {
set winfo [dict get $workers $sourcetag] set winfo [dict get $workers $sourcetag]
if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} { if {[dict get $winfo tid] ne "noop" && [thread::exists [dict get $winfo tid]]} {
# add our client-info to existing worker thread # add our client-info to existing worker thread
set existing_settings [get_tag_config $sourcetag]
if {$settingsdict eq $existing_settings} {
#same settings - share the worker
dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid]
} elseif {$existing_settings eq {-raw 0 -file {} -syslog {} -direction out}} {
#review - magic dict seems brittle - shouldn't hard code here.???
dict lappend winfo list_client_tids $tidclient dict lappend winfo list_client_tids $tidclient
dict set workers $sourcetag $winfo ;#writeback dict set workers $sourcetag $winfo ;#writeback
return [dict get $winfo tid] return [dict get $winfo tid]
} else {
set emsg "shellthread::manager::new_worker error: tag $sourcetag already has a worker with a different configuration\n"
append emsg "existing: $existing_settings\n"
append emsg "attempted: $settingsdict\n"
append emsg "workers info: $winfo"
error $emsg
}
} }
} }
@ -508,7 +527,9 @@ namespace eval shellthread::manager {
if {[llength $free_threads]} { if {[llength $free_threads]} {
#todo - re-use from tail - as most likely to have been doing similar work?? review #todo - re-use from tail - as most likely to have been doing similar work?? review
set free_threads [lassign $free_threads tidworker] #set free_threads [lassign $free_threads tidworker]
set tidworker [lpop free_threads 0]
#todo - keep track of real ts_start of free threads... kill when too old #todo - keep track of real ts_start of free threads... kill when too old
set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]] set winfo [dict create tid $tidworker list_client_tids [list $tidclient] ts_start $ts_start ts_end_list [list] workertype [dict get $settingsdict -workertype]]
#puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag" #puts stderr "shellfilter::new_worker Re-using free worker thread: $tidworker with tag $sourcetag"
@ -641,7 +662,7 @@ namespace eval shellthread::manager {
proc unsubscribe {sourcetaglist} { proc unsubscribe {sourcetaglist} {
variable workers variable workers
#workers structure example: #workers structure example:
#[list sourcetag1 [list tid <tidworker> list_client_tids <clients>] ts_start <ts_start> ts_end_list {}] #[list sourcetag1 [list tid <tidworker> list_client_tids <clients> ts_start <ts_start> ts_end_list {} workertype message|pipe]]
variable free_threads variable free_threads
set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread set mytid [thread::id] ;#caller of shellthread::manager::xxx is the client thread
@ -684,6 +705,9 @@ namespace eval shellthread::manager {
foreach workertid $subscriberless_workers { foreach workertid $subscriberless_workers {
if {$workertid ni $shuttingdown_workers} { if {$workertid ni $shuttingdown_workers} {
if {$workertid ni $free_threads && $workertid ne "noop"} { if {$workertid ni $free_threads && $workertid ne "noop"} {
#JMN
thread::send $workertid {set ::shellthread::worker::settings $::shellthread::worker::settings_defaults}
#todo - log freeing up of thread
lappend free_threads $workertid lappend free_threads $workertid
} }
} }
@ -704,6 +728,16 @@ namespace eval shellthread::manager {
return $taginfo_list return $taginfo_list
} }
proc get_tag_config {tag} {
#review
variable workers
if {![dict exists $workers $tag]} {
error "shellthread::manager::get_tag_config error no existing tag $tag"
}
set workertid [dict get $workers $tag tid]
set conf [thread::send $workertid {set ::shellthread::worker::settings}]
}
#finalisation #finalisation
proc shutdown_free_threads {{timeout 2500}} { proc shutdown_free_threads {{timeout 2500}} {
variable free_threads variable free_threads

9489
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/tomlish-1.1.8.tm

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save