Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CatapultClient.Close() fails consistently due to race condition #36

Open
avanaur opened this issue Jun 12, 2019 · 0 comments
Open

CatapultClient.Close() fails consistently due to race condition #36

avanaur opened this issue Jun 12, 2019 · 0 comments
Labels
bug Something isn't working

Comments

@avanaur
Copy link

avanaur commented Jun 12, 2019

Whenever I tried Close(), it always fails with the error below.

panic: close tcp 192.168.20.11:64395->52.221.198.188:3000: use of closed network connection

goroutine 69 [running]:
github.com/proximax-storage/go-xpx-catapult-sdk/sdk/websocket.(*CatapultWebsocketClientImpl).Listen(0xc000388000)
	C:/Users/Tyrone/go/src/github.com/proximax-storage/go-xpx-catapult-sdk/sdk/websocket/client.go:162 +0x24a
created by main.testWS
	C:/Users/Tyrone/go/src/github.com/proximax-storage/csd-test-playground/test_websocket/main.go:56 +0x1a0

My understanding is there is a race condition on Close() and Listen(). Upon Close(), Listen() would immediately run the first case below.

	for {
		select {
		case <-c.ctx.Done():
			if c.conn != nil {
				if err := c.conn.Close(); err != nil {
					panic(err)
				}
				c.conn = nil
			}
			return
		case msg := <-messagesChan:
			go c.messageRouter.RouteMessage(msg)
		}
	}

My code:

	conf, err := sdk.NewConfig([]string{"http://csddev1.xpxsirius.io:3000", "http://csddev2.xpxsirius.io:3000"}, sdk.PrivateTest, sdk.WebsocketReconnectionDefaultTimeout)
	if err != nil {
		panic(err)
	}

	ctx, cancel := context.WithTimeout(context.TODO(), time.Second*30)
	wsClient, err := websocket.NewClient(ctx, conf)
	if err != nil {
		panic(err)
	}
	go wsClient.Listen()

	address, err := sdk.NewAddressFromRaw("WAFSWQIF2UBLBHOFOYMIQJXZKRSTNONZIM6VYAZT")
	if err != nil {
		panic(err)
	}

	txn, err := sdk.NewTransferTransaction(
		sdk.NewDeadline(time.Hour),
		address,
		[]*sdk.Mosaic{},
		sdk.NewPlainMessage(fmt.Sprintf("hi there %d", rand.Int())),
		sdk.PrivateTest,
	)
	if err != nil {
		panic(err)
	}

	acct, err := sdk.NewAccountFromPrivateKey("b007b006c2178a8819c6b38dd3b49db1c2170483fdfcff21656f071c7541b5a9", sdk.PrivateTest)
	if err != nil {
		panic(err)
	}

	signedTxn, err := acct.Sign(txn)
	if err != nil {
		panic(err)
	}

	var wg sync.WaitGroup
	wg.Add(1)
	err = wsClient.AddUnconfirmedAddedHandlers(address, func(txn sdk.Transaction) bool {
		fmt.Println("FOUND", txn.GetAbstractTransaction().Hash.String())
		if txn.GetAbstractTransaction().Hash.String() == signedTxn.Hash.String() {
			fmt.Println("FOUND HASH IT ON UNCONFIRMED", txn.GetAbstractTransaction().Hash.String())
			wg.Done()
		}
		return false
	})
	if err != nil {
		panic(err)
	}

	client := sdk.NewClient(nil, conf)
	_, err = client.Transaction.Announce(context.Background(), signedTxn)
	fmt.Println("ANNOUNCED", signedTxn.Hash)
	if err != nil {
		panic(err)
	}

	wg.Wait()

	wsClient.Close()

My workaround right now is to use context's cancel function. It works most of the time but has a separate issue.

@avanaur avanaur added the bug Something isn't working label Jun 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant