Any ideas on the cause of this error below?
It happens during a http request to a local machine in the LAN.
I cannot debug this, since it happens on a machine of a customer.
It works for me, when I connect to the same machine over VPN.
too many nested evaluations (infinite loop?)
The http request is hooked up to a callback procedures that updates a progress bar variable:
## Update the variable of the main progress bar when uploading or
downloading files.
# \param token token of the http transaction if this progress bar
reflects e.g. an upload or download process
# \param expected the amount of bytes expected in case of an upload or download process. Any integer number in other cases.
# \param received the amount of bytes received in case of an upload or download process. Any integer number in other cases.
# \return
proc ::UIProgressBar {token expected received} {
if {$expected==0} {
return
}
set ::progress [expr {int(100.0 *
double($received)/double($expected))}]
update
Thanks Ralph, I get it now.
I'll experiment with your suggestions.
Regards
Alexandru
* alexandru.dadalau@meshparts.de (alexandru)
| Thanks, but what is the point in updating a progress bar only when the
| user makes a click?
Good question :-). Interactive events are bound to happen in at least milliseconds intervalls, so there is aeons of time for the computer to
update the screen, thus [update] is not necessary at all.
The problem usually is that the events happen so quickly that the 'idle' handler (which does the screen update in Tk) has no chance to run.
Consider a 'readable' fileevent on a regular large file: this will
trigger repeatedly until EOF, and any change to widgets (eg, "read N% complete") will not be visible until EOF, where it jumps from 0% to 100%.
R'
# Pause briefly to simulate processing time
after 100
}
# Send signal to main thread to update the progress variable
thread::send -async \$main_thread_id \[list handle_http_event \$increment_value \$max_progress_var\]
et99 <et99@rocketship1.me> wrote:
# Send signal to main thread to update the progress variable
thread::send -async \$main_thread_id \[list handle_http_event \$increment_value \$max_progress_var\]
Did it really write the above.
This will try to send to the thread id "$main_thread_id" (which, btw, is
not a thread ID that returns from thread::create) and will likely error
out for "too many arguments" before it errors out for "thread ID not
found" as thread::send takes at most three (ignoring option switches)
and the third one is a varname to save the result into when the script
exits.
I.e., it got the quoting all messed up.
On 5/30/2024 3:33 PM, Rich wrote:
et99 <et99@rocketship1.me> wrote:
# Send signal to main thread to update the progress variable
thread::send -async \$main_thread_id \[list handle_http_event \$increment_value \$max_progress_var\]
Did it really write the above.
This will try to send to the thread id "$main_thread_id" (which, btw, is
not a thread ID that returns from thread::create) and will likely error
out for "too many arguments" before it errors out for "thread ID not
found" as thread::send takes at most three (ignoring option switches)
and the third one is a varname to save the result into when the script
exits.
I.e., it got the quoting all messed up.
If you look again, you will see that the script is defined using:
set script "....
"
I've just now asked it to stop using so many globals, so it re-wrote
it using a namespace.
et99 <et99@rocketship1.me> wrote:
On 5/30/2024 3:33 PM, Rich wrote:
et99 <et99@rocketship1.me> wrote:
# Send signal to main thread to update the progress variable
thread::send -async \$main_thread_id \[list handle_http_event \$increment_value \$max_progress_var\]
Did it really write the above.
This will try to send to the thread id "$main_thread_id" (which, btw, is >>> not a thread ID that returns from thread::create) and will likely error
out for "too many arguments" before it errors out for "thread ID not
found" as thread::send takes at most three (ignoring option switches)
and the third one is a varname to save the result into when the script
exits.
I.e., it got the quoting all messed up.
If you look again, you will see that the script is defined using:
set script "....
"
Ah, yes, I did miss that little bit.
I've just now asked it to stop using so many globals, so it re-wrote
it using a namespace.
Yeah, I did notice, but did not comment on, the use of globals there.
It is interesting that it did not simply go the namespace route from
the start. Since if it could do it after you asked, it presumably
"knew how" when it wrote the version with the globals.
On 5/31/2024 9:27 AM, Rich wrote:
Yeah, I did notice, but did not comment on, the use of globals
there.
It is interesting that it did not simply go the namespace route from
the start. Since if it could do it after you asked, it presumably
"knew how" when it wrote the version with the globals.
Yeah, it seems to like to use globals a lot. Perhaps internet
training data uses globals more than namespaces. In its final code
it's again using some globals, but I didn't ask it to fix that.
One puzzle: I added some puts statements and I often see the http
progress callback occurring repeatedly with the same bytes
transferred.
But since this doesn't increase the percent done, it doesn't try to
update the progress. Maybe this is why Alexandru was having
problems???
I then tested it out on some web pages, like wikipedia home page, and
one longer page I found ("https://tkdocs.com/tutorial/onepage.html")
but it doesn't always return an expected size value (returning 0 in
that case).
et99 <et99@rocketship1.me> wrote:
On 5/31/2024 9:27 AM, Rich wrote:
One puzzle: I added some puts statements and I often see the http
progress callback occurring repeatedly with the same bytes
transferred.
Not surprising. When asked to run the callback the module reads in
chunks of -blocksize, so each callback will be after -blocksize bytes
of the body of the http request have arrived.
Note from the http manpage:
-blocksize size
The block size used when reading the URL. At most size bytes are
read at once. After each block, a call to the -progress callback
is made (if that option is specified).
And in at least the 2.9.5 version that ships with Tcl 8.6.12
-blocksize defaults to 8192 bytes if not specified by the caller.
On 5/31/2024 12:32 PM, Rich wrote:
et99 <et99@rocketship1.me> wrote:
On 5/31/2024 9:27 AM, Rich wrote:
One puzzle: I added some puts statements and I often see the http
progress callback occurring repeatedly with the same bytes
transferred.
Not surprising. When asked to run the callback the module reads in
chunks of -blocksize, so each callback will be after -blocksize
bytes of the body of the http request have arrived.
Note from the http manpage:
-blocksize size
The block size used when reading the URL. At most size bytes
are read at once. After each block, a call to the -progress
callback is made (if that option is specified).
And in at least the 2.9.5 version that ships with Tcl 8.6.12
-blocksize defaults to 8192 bytes if not specified by the caller.
That makes sense, but I would expect it to call the callback with a
new value for bytes transferred, not the same value.
And I did use a -blocksize 1500 and I still see values like, 16384
repeated 5 times, then 32768 (this is on windows) so that would seem
to indicate it's reading in blocks of 2*8192 (same with 8.6.9 and
8.6.13). Also, it even did 4 callbacks at the start with a value of
0.
et99 <et99@r...........> wrote:
On 5/31/2024 12:32 PM, Rich wrote:
It is not reporting "total bytes so far" it is reporting "bytes for
this callback". The callback has to take care of totalling things up
if that is what it wants.
And I did use a -blocksize 1500 and I still see values like, 16384
repeated 5 times, then 32768 (this is on windows) so that would seem
to indicate it's reading in blocks of 2*8192 (same with 8.6.9 and
8.6.13). Also, it even did 4 callbacks at the start with a value of
0.
Unsure on that. Probably it is calling the callback per event loop
cycle, and if the read event fires for some reason, but there are no
bytes, you'd see a zero. Or else those are for the headers and it just reports zero for headers (as headers are not body bytes).
Why the size is larger than what you set for blocksize I can't say.
On 5/31/2024 2:14 PM, Rich wrote:
et99 <et99@r...........> wrote:
On 5/31/2024 12:32 PM, Rich wrote:
It is not reporting "total bytes so far" it is reporting "bytes for
this callback". The callback has to take care of totalling things
up if that is what it wants.
Here's the manpage on -progress
-progress callback
The callback is made after each transfer of data from the URL.
The callback gets three additional arguments: the token from
::http::geturl, the expected total size of the contents from the
Content-Length meta-data, and the *current number of bytes
transferred so far*. The expected total size may be unknown, in
which case zero is passed to the callback.
(emphasis added)
And I did use a -blocksize 1500 and I still see values like, 16384
repeated 5 times, then 32768 (this is on windows) so that would seem
to indicate it's reading in blocks of 2*8192 (same with 8.6.9 and
8.6.13). Also, it even did 4 callbacks at the start with a value of
0.
Unsure on that. Probably it is calling the callback per event loop
cycle, and if the read event fires for some reason, but there are no
bytes, you'd see a zero. Or else those are for the headers and it just
reports zero for headers (as headers are not body bytes).
Why the size is larger than what you set for blocksize I can't say.
Here's the output of the program, it outputs last_percent... only
when it updates the progress bar, so only when the bytes_transferred
has increased:
start
inside-start
token= |::http::1| total_size= |170427| bytes_transferred= |0|
last_percent= |-1| progress= |0|
token= |::http::1| total_size= |170427| bytes_transferred= |0|
token= |::http::1| total_size= |170427| bytes_transferred= |0|
token= |::http::1| total_size= |170427| bytes_transferred= |0|
token= |::http::1| total_size= |170427| bytes_transferred= |16384| last_percent= |0| progress= |9|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |16384|
token= |::http::1| total_size= |170427| bytes_transferred= |32768|
et99 <et99@rocketship1.me> wrote:
On 5/31/2024 2:14 PM, Rich wrote:
et99 <et99@r...........> wrote:
On 5/31/2024 12:32 PM, Rich wrote:
Indeed, that is unexpected.
I get the same result on Linux:
Just with slightly different amount of data transferred each callback.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 498 |
Nodes: | 16 (0 / 16) |
Uptime: | 74:13:02 |
Calls: | 9,819 |
Calls today: | 7 |
Files: | 13,757 |
Messages: | 6,189,860 |