Bugswriter / tuxi

Tuxi is a cli assistant. Get answers of your questions instantly.
GNU General Public License v3.0
1.33k stars 73 forks source link

Super Mega Ultra Small update #184

Closed BeyondMagic closed 2 years ago

BeyondMagic commented 3 years ago

Just cleaned a little bit the code and made more friendly looking, I guess, give it a look. I started making this a few weeks ago and just forgot, ι(`ロ´)ノ.

It stills a draft because I can't figure out how to stop the duplicate answer of a few queries, like math. I think this is causing it?!

[ ! $all ] && {
    for lucky_winner in $(printf '%b\n' "$pids"); do

        [ $printed -gt 0 ] && break
        kill -0 "$lucky_winner" 1>/dev/null 2>&1

        [ $? -eq 0 ]  && {
            kill -USR1 "$lucky_winner" 1>/dev/null 2>&1
            short_delay
        }

    done
}

Also added a function example in the README for tuxi, something that may be useful for users trying to get something fast and easier from tuxi.

Fixes #179.

PureArtistry commented 3 years ago

That is a bug that can't be fixed without making fundamental changes to the processing code, it can only be mitigated (that is what the short_delay if for)

The problem is that once you fork something you can't directly "talk" with it anymore, it now exists in it's own separate memory space and processes can only see their own memory.

The (admittedly very janky) system I used in the script is a sort of message passing system using kill. The script reaches the point you've highlighted when one of the forks has sent the message to the main script to say it as found an answer, it does this by sending the kill -USR1 signal back to the main pid which gets caught and then the main script runs this $(($answers_found + 1))

that breaks the main script out of the loop it was in previously and it moves on to the code you posted above, at this point the main script knows a fork is ready to print an answer but it can't know which one.

I'll emphasise here, it's not the main pid that prints the answer - that would require a way for the fork to send the answer back to the main pid, this is something that can be achieved with a socket/fifo file but will need a chunk of the code to be re-written (something I don't mind doing in the future but that is at least a few weeks away)

we're now at the code above, the main pid knows an answer is ready but not which fork so it has to go through the list of forks checking each one. first it sends the kill -0 signal to ask if the fork is still running, if a fork doesn't find an answer it just exits and kill will return a 1. if it returns 0 the main pid knows that particular fork is still running but not what it's status is, it could still be processing the answer or ready to print

this next bit is what causes the bug - if the fork is still running the main pid then sends the kill -USR1 signal to that fork. if the fork is still processing the answer this will do nothing but if the fork is ready to print the answer it will send the kill -USR2 signal back to the main pid and print the answer out when the main pid recieves the -USR2 signal it runs printed=$(($printed + 1)) which will then break the loop above

The problem is that these signals aren't instant, it takes a while (relatively speaking) for the main pid to run kill, the fork to recieve that signal then itself run kill, the main pid then recieves that signal after a time and increments the printed variable which the loop is checking as an exit condition

this is what the small delay is about, to give to time for all those signals to be passed around, if it is too short then on the next iteration of the loop printed will still be at 0 so another -USR1 gets sent out causing a second answer to be printed (or a duplicate if that is the only pid still running with an answer)

basically until the processing code has been re-written the only way to prevent this is to just increase the delay, I very rarely get multiple answers on my system with it at 250 and never duplicates - try raising it to 400 or whatever if you are often getting multiple answers.

If you need me to elaborate more on this let me know

PureArtistry commented 3 years ago

btw, forgot to mention - script looks much cleaner / more readable, nice work

BeyondMagic commented 3 years ago

Wow, thanks for all the explanation, I was really wondering if I did change something in the code and made it runs faster or slower, I don't know, the thing is that I really have a lot of duplicates when running this new code, so is something with the spaces or comments or, you know, newlines that I added; because I don't think I did change the process of any function, right? It's just a few aliases, a few repositions, etc...

I increased the value to test out, 500, then 1000, then 5000, then back to 100, but stills printing out duplicates for this specific snippet; though it fixes for some. Can you test it?

image

PureArtistry commented 3 years ago

you have alterted something in a significant way as it seems to be running the tests twice which is why you're seeing more duplicate answers.

I'll have to properly look through your changes to see what is going on

BeyondMagic commented 3 years ago

The all variable is very strange... seems to be fixed now. I'll make the same with the tests script and it'll be done.

BeyondMagic commented 3 years ago

Well, today I discovered that if ! true; then is completely different compared to [ ! true ] &&...

BeyondMagic commented 3 years ago

@PureArtistry Alright, give it a test because I think it's ready.