If a IRC-User joins a channel, this happens:

  1. JOIN channel
  2. server acknowledges the JOIN
  3. ???
  4. WHO channel
  5. ???
  6. list of people in the channel, ENDOFWHO

if a plugin would react on .joined(channel), it cannot use the userlist, because the userlist is only filled after ENDOFWHO. even worse, events like userQuit, userLeft, etc. cannot update the userlist until ENDOFWHO. so after ENDOFWHO the userlist may be even too long without synchronisation.

synced* decorators

every function which may depend on the userlist is decorated by otfbot.services.ircClient.synced… decorator.

the decorators do the following:

  • if everything is synced, just execute the function
  • if the needed data (channel for events like userLeft, everything for events like userQuit) isn't there yet, append to a queue, then return.

irc_ENDOFWHO looks into the event-queues, and executed the delayed callbacks in first-in-first-out order. so now the order may look like this:

  1. join
  2. userQuit(foo) → queue
  3. userJoined(bar, channel) → queue
  4. msg(channel, user, “userlist”)
  5. ENDOFWHO, userlist is there
  6. now execute userQuit(foo)
  7. now execute userJoined(bar, channel)
  8. now execute msg callback → i.e. print the correct userlist