~badt/telebot

11cbaeaf0e8b1c1bbd4b2a42088ebdcb56cf5ecf — Ilya 1 year, 10 months ago fa98776 + 4d903fb
Merge pull request #532 from codemorego/v3-do-cancel-poll-on-bot-stop-immediately

do cancel poll immediately on bot stop
3 files changed, 37 insertions(+), 2 deletions(-)

M api.go
M bot.go
M util.go
M api.go => api.go +23 -1
@@ 2,6 2,7 @@ package telebot

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"


@@ 26,7 27,28 @@ func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
		return nil, err
	}

	resp, err := b.client.Post(url, "application/json", &buf)
	// Cancel the request immediately without waiting for the timeout  when bot is about to stop.
	// This may become important if doing long polling with long timeout.
	exit := make(chan struct{})
	defer close(exit)
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	go func() {
		select {
		case <-b.stopClient:
			cancel()
		case <-exit:
		}
	}()

	req, err := http.NewRequestWithContext(ctx, "POST", url, &buf)
	if err != nil {
		return nil, wrapError(err)
	}
	req.Header.Set("Content-Type", "application/json")

	resp, err := b.client.Do(req)
	if err != nil {
		return nil, wrapError(err)
	}

M bot.go => bot.go +11 -0
@@ 79,6 79,7 @@ type Bot struct {
	parseMode   ParseMode
	stop        chan chan struct{}
	client      *http.Client
	stopClient  chan struct{}
}

// Settings represents a utility struct for passing certain


@@ 207,6 208,12 @@ func (b *Bot) Start() {
		panic("telebot: can't start without a poller")
	}

	// do nothing if called twice
	if b.stopClient != nil {
		return
	}
	b.stopClient = make(chan struct{})

	stop := make(chan struct{})
	stopConfirm := make(chan struct{})



@@ 225,6 232,7 @@ func (b *Bot) Start() {
			close(stop)
			<-stopConfirm
			close(confirm)
			b.stopClient = nil
			return
		}
	}


@@ 232,6 240,9 @@ func (b *Bot) Start() {

// Stop gracefully shuts the poller down.
func (b *Bot) Stop() {
	if b.stopClient != nil {
		close(b.stopClient)
	}
	confirm := make(chan struct{})
	b.stop <- confirm
	<-confirm

M util.go => util.go +3 -1
@@ 14,7 14,9 @@ var defaultOnError = func(err error, c Context) {
}

func (b *Bot) debug(err error) {
	log.Println(err)
	if b.verbose {
		log.Println(err)
	}
}

func (b *Bot) deferDebug() {