The issue with Go routines and their use in tasks (in sneaker bots) is stopping them when a user requests it. As you know modern bots have stop functions for each task, which sparked me to create this for Go.
I have used channels to signal a go routine to stop. Two new channels are created when you start a task:
- TaskIDStop
- TaskIDStopped
These channels are unique. They are then stored in an array, known as "taskArray". I use a struct to form this array, which consists of your Task ID and your two unique channels.
To start a task, you would create both channels and a Task ID. This item would then be appended to taskArray, and then you call your function:
go Task(task.taskIDStop, task.taskIDStopped, &waitgroup)
After you have started your task, you can now stop it at any time.
Note task.taskIDStop and task.taskIDStopped are chan struct{}.
To stop the task you call:
stop(TaskID)
Beneath the hood, this is:
Find index of TaskID in taskArray (i)
Close the taskIDStop channel (i)
Wait for the taskIDStopped channel (i) to close upon the go routine exit
Return task stopped to UI
Remove task from taskArray
This finds the specified task in your task array, and the related channels. It then closes the taskIDStop channel.
To know when the channel has closed, for each operation in your function you would check using a select statement, like so:
defer close(taskIDStopped)
Select {
default:
// ATC, Submit checkout etc
case <-taskIDStop:
waitgroup.Done()
return
//Task exits
//Closes taskIDStopped upon exit
}
You must defer the closing of the taskIDStopped channel. Defering the closing will allow it to close the channel when your go routine exits, therefore signaling your go routine has stopped successfully.