From dae78a67377c706591c2b0b049e7a3abbe97389c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Pastor=20P=C3=A9rez?= Date: Sun, 24 May 2026 18:03:26 +0200 Subject: [PATCH 1/2] integrations: Fix IRC mirror timing out when relaying IRC messages. * zulip/integrations/bridge_with_irc/irc_mirror_backend.py (fresh_session): New procedure. Ensure forked processes have a clean client to ensure they don't share the SSL sockets of the parent. --- .../integrations/bridge_with_irc/irc_mirror_backend.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py index 8fdd6c98f..beffbc7ce 100644 --- a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py +++ b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py @@ -89,7 +89,15 @@ def forward_to_irc(msg: Dict[str, Any]) -> None: for line in msg["content"].split("\n"): send(line) - z2i = mp.Process(target=self.zulip_client.call_on_each_message, args=(forward_to_irc,)) + def forward_zulip_to_irc() -> None: + # Create a new client so the child doesn't share the parent's SSL + # sockets after forking in 'mp.Process'. + self.zulip_client.session.close() + self.zulip_client.session = None + self.zulip_client.ensure_session() + self.zulip_client.call_on_each_message(forward_to_irc) + + z2i = mp.Process(target=forward_zulip_to_irc) z2i.start() def on_privmsg(self, c: ServerConnection, e: Event) -> None: From 4261ed93433037e69bc6f4e7fc52a5c482b9d00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Pastor=20P=C3=A9rez?= Date: Fri, 22 May 2026 10:56:48 +0200 Subject: [PATCH 2/2] build: make IRC mirror integration script installable. This change was originally proposed by Sharlatan Hellseher: https://codeberg.org/guix/guix/pulls/7418#issuecomment-12239616 * zulip/integrations/bridge_with_irc/irc-mirror.py: Rename file to 'irc_mirror.py' to make it importable as a Python module. * zulip/integrations/bridge_with_irc/irc_mirror.py: Introduce `main' entry point so it can be used as a setuptools console script entry point. * zulip/setup.py: Register 'zulip-irc-bridge' as a console script so it's installed as part of the package output. --- .../bridge_with_irc/{irc-mirror.py => irc_mirror.py} | 9 +++++++-- zulip/setup.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) rename zulip/integrations/bridge_with_irc/{irc-mirror.py => irc_mirror.py} (95%) diff --git a/zulip/integrations/bridge_with_irc/irc-mirror.py b/zulip/integrations/bridge_with_irc/irc_mirror.py similarity index 95% rename from zulip/integrations/bridge_with_irc/irc-mirror.py rename to zulip/integrations/bridge_with_irc/irc_mirror.py index 7aaca7b96..8d9bbee58 100755 --- a/zulip/integrations/bridge_with_irc/irc-mirror.py +++ b/zulip/integrations/bridge_with_irc/irc_mirror.py @@ -27,7 +27,8 @@ Note that "_zulip" will be automatically appended to the IRC nick provided """ -if __name__ == "__main__": + +def main() -> None: parser = zulip.add_default_arguments( argparse.ArgumentParser(usage=usage), allow_provisioning=True ) @@ -45,7 +46,7 @@ options.client = "irc_mirror" zulip_client = zulip.init_from_options(options) try: - from irc_mirror_backend import IRCBot + from .irc_mirror_backend import IRCBot # type: ignore[import-untyped] except ImportError: traceback.print_exc() print( @@ -70,3 +71,7 @@ sasl_password=options.sasl_password, ) bot.start() + + +if __name__ == "__main__": + main() diff --git a/zulip/setup.py b/zulip/setup.py index 097bc684b..236e5d747 100755 --- a/zulip/setup.py +++ b/zulip/setup.py @@ -60,6 +60,7 @@ def recur_expand(target_root: Any, dir: Any) -> Generator[Tuple[str, List[str]], "zulip-send=zulip.send:main", "zulip-api-examples=zulip.api_examples:main", "zulip-matrix-bridge=integrations.bridge_with_matrix.matrix_bridge:main", + "zulip-irc-bridge=integrations.bridge_with_irc.irc_mirror:main", "zulip-api=zulip.cli:cli", ], },