Skip to content

Fixed a bug when subscribing and unsubscribing in callback handling#42

Merged
ThomasTJdev merged 2 commits intomasterfrom
separate_call_callbacks
Aug 7, 2025
Merged

Fixed a bug when subscribing and unsubscribing in callback handling#42
ThomasTJdev merged 2 commits intomasterfrom
separate_call_callbacks

Conversation

@python36
Copy link
Copy Markdown
Owner

Any manipulation of topics (subscription or unsubscription) changes the length of the callback list in the iteration cycle and causes an exception.

For example:

import nmqtt
import asyncdispatch

let ctx = newMqttCtx("test")
ctx.setHost("localhost", 1883)

proc secondOnMsg(topic: string, messageRaw: string) =
  echo "second"

proc subs(topic: string) {.async.} =
  await ctx.subscribe(topic, 0, secondOnMsg)

proc firstOnMsg(topic: string, messageRaw: string) =
  echo "first"
  waitFor subs("second_topic")

proc mqttSub() {.async.} =
  await ctx.start()
  await ctx.subscribe("first_topic", 0, firstOnMsg)

asyncCheck mqttSub()
runForever()

Raise next exception:

Hint: used config file '/home/user/.choosenim/toolchains/nim-2.2.4/config/nim.cfg' [Conf]
Hint: used config file '/home/user/.choosenim/toolchains/nim-2.2.4/config/config.nims' [Conf]
.............................................................................................................................................
/opt/machina/test.nim(7, 7) Hint: 'baseTopicWill' is declared but not used [XDeclaredButNotUsed]
/opt/machina/test.nim(9, 5) Hint: 'log' is declared but not used [XDeclaredButNotUsed]
/opt/machina/test.nim(5, 8) Warning: imported and not used: 'lists' [UnusedImport]
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/system/exceptions.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/private/digitsutils.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/assertions.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/objectdollar.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/system/dollars.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/syncio.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/system.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/math.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/algorithm.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/strutils.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/oserrors.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/private/ospaths2.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/options.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/times.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/envvars.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/cmdline.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/hashes.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/tables.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/heapqueue.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/sets.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/deques.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncfutures.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/std/monotimes.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/nativesockets.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/net.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/selectors.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncmacro.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim
CC: ../../home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncnet.nim
CC: ../../home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim
CC: logger.nim
CC: test.nim
Hint:  [Link]
Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
70387 lines; 2.221s; 140.688MiB peakmem; proj: /opt/machina/test.nim; out: /opt/machina/test [SuccessX]
Hint: /opt/machina/test [Exec]
first
/opt/machina/test.nim(63) test
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(2018) runForever
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1712) poll
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1453) runOnce
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/threadimpl.nim(269) processPendingCallbacks
/home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1050) runRx (Async)
/home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1024) handle (Async)
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/tables.nim(771) onPublish (Async)
/home/user/.choosenim/toolchains/nim-2.2.4/lib/std/assertions.nim(41) failedAssertImpl
/home/user/.choosenim/toolchains/nim-2.2.4/lib/std/assertions.nim(36) raiseAssert
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/fatal.nim(53) sysFatal
[[reraised from:
/opt/machina/test.nim(63) test
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(2018) runForever
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1712) poll
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1453) runOnce
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/threadimpl.nim(269) processPendingCallbacks
/home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1050) runRx (Async)
/home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1024) handle (Async)
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncfutures.nim(370) read
]]
[[reraised from:
/opt/machina/test.nim(63) test
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(2018) runForever
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1712) poll
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1453) runOnce
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/threadimpl.nim(269) processPendingCallbacks
/home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1050) runRx (Async)
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncfutures.nim(370) read
]]
[[reraised from:
/opt/machina/test.nim(63) test
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(2018) runForever
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1712) poll
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1453) runOnce
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/threadimpl.nim(269) processPendingCallbacks
/home/user/.choosenim/toolchains/nim-2.2.4/lib/std/typedthreads.nim(287) runRx (Async)
]]
[[reraised from:
/opt/machina/test.nim(63) test
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(2018) runForever
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1712) poll
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncdispatch.nim(1453) runOnce
/home/user/.choosenim/toolchains/nim-2.2.4/lib/system/threadimpl.nim(269) processPendingCallbacks
/home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/asyncfutures.nim(428) asyncCheckCallback
]]
Error: unhandled exception: /home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/tables.nim(771, 13) `len(t) == L` the length of the table changed while iterating over it
Async traceback:
  /opt/machina/test.nim(63) test
  /home/user/.choosenim/toolchains/nim-2.2.4/lib/std/typedthreads.nim(287) runRx (Async)
  /home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1050) runRx (Async)
  /home/user/.nimble/pkgs2/nmqtt-1.0.6-926c1e352673c57dcb3cdefc20cf0ca5a454d81e/nmqtt.nim(1024) handle (Async)
  /home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/tables.nim(771) onPublish (Async)
  /home/user/.choosenim/toolchains/nim-2.2.4/lib/std/assertions.nim(41) failedAssertImpl
  /home/user/.choosenim/toolchains/nim-2.2.4/lib/std/assertions.nim(36) raiseAssert
  /home/user/.choosenim/toolchains/nim-2.2.4/lib/system/fatal.nim(53) sysFatal
Exception message: /home/user/.choosenim/toolchains/nim-2.2.4/lib/pure/collections/tables.nim(771, 13) `len(t) == L` the length of the table changed while iterating over it
 [AssertionDefect]
Error: execution of an external program failed: '/opt/machina/test'

@ThomasTJdev
Copy link
Copy Markdown
Collaborator

@zevv - Something looks different to me in the repo settings. Could you try to enable Github Workflows to run on first-time-committers? Or provide me access to those repo-settings?

@python36 - Could you please try to run the same code with Nim v1.6.18 (choosenim 1.6.18)? Sorry for not getting back to you before now.

@ThomasTJdev ThomasTJdev merged commit 43bc7bc into python36:master Aug 7, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants