I made a simple web app using Go. there is a goroutine
which is executed when user access a URL, let say /inspection/start/
. how to stop that goroutine
when user access URL /inspection/stop/
?
I heard about channel
but I am not sure how to do it in my case.
here is the code:
func inspection_form_handler(w http.ResponseWriter, r *http.Request) {
if r.FormValue("save") != "" {
airport_id := getCurrentAirportId(r)
r.ParseForm()
if airport_id != nil {
if r.FormValue("action") == "add"{
go read_serial_port()
}
// redirect back to the list
http.Redirect(w, r, "/airport#inspect", http.StatusSeeOther)
}
}
}
the routine function
func read_serial_port(){
c := &serial.Config{Name:"/dev/ttyACM0", Baud:9600}
s, err := serial.OpenPort(c)
if err != nil {
log.Fatal(err)
}
filename:= randSeq(10)+".txt"
file, _ := os.Create("output/"+filename)
defer file.Close();
for{
buf := make([]byte, 128)
n, err := s.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Printf("%s", string(buf[:n]))
fmt.Fprintf(file, string(buf[:n]))
time.Sleep(100 * time.Millisecond)
}
}
you can make it by using time ticker and context
func read_serial_port(c context.Context){
c := &serial.Config{Name:"/dev/ttyACM0", Baud:9600}
s, err := serial.OpenPort(c)
if err != nil {
log.Fatal(err)
}
filename:= randSeq(10)+".txt"
file, _ := os.Create("output/"+filename)
defer file.Close();
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for{
select {
case <-c.Done():
break
case <-ticker.C:
buf := make([]byte, 128)
n, err := s.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Printf("%s", string(buf[:n]))
fmt.Fprintf(file, string(buf[:n]))
time.Sleep(100 * time.Millisecond)
}
}
}
then you need to add another route to call the cancel function
if r.FormValue("action") == "add"{
c, cnl := context.WithCancel(context.Background())
// need to access this cancel function to use it in another route
ExportedFunction = cnl
go read_serial_port()
}
then cancel it by:
func abortingMission(w http.ResponseWriter, r *http.Request) {
ExportedFunction()
}
and also DON'T use underscore in your function name