Skip to content

Fix zip observable to upstream (v2)#2040

Merged
alexandru merged 5 commits into
mainfrom
fix-zip-observable-to-upstream
Apr 27, 2026
Merged

Fix zip observable to upstream (v2)#2040
alexandru merged 5 commits into
mainfrom
fix-zip-observable-to-upstream

Conversation

@alexandru
Copy link
Copy Markdown
Member

@alexandru alexandru commented Apr 27, 2026

Continuation of this PR: #2029

Original: https://github.com/AVSystem/monix/pull/1]

Changes:

  1. Avoids re-entrant synchronization in onComplete by avoiding lock.synchronize in signalOnComplete
  2. Changes the implementation of signalOnError to require lock.synchronize at the call-site, matching signalOnComplete and signalOnNext (all require synchronization at the call-site now) … this makes the need for synchronization clearer

@alexandru alexandru requested a review from Copilot April 27, 2026 08:44
@alexandru alexandru changed the title Fix zip observable to upstream Fix zip observable to upstream (v2) Apr 27, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns Zip{2..6}Observable synchronization behavior with upstream by removing internal lock.synchronized from signalOnComplete / signalOnError and requiring synchronization at call-sites, avoiding re-entrant locking in completion paths.

Changes:

  • Wraps signalOnComplete(false) with lock.synchronized in the ack.onComplete callback to avoid re-entrant synchronization inside signalOnComplete.
  • Refactors signalOnError and signalOnComplete to require lock synchronization at the call-site (call-sites updated accordingly).
  • Adds/updates inline documentation clarifying the required locking contract (in most ZipN variants).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
monix-reactive/shared/src/main/scala/monix/reactive/internal/builders/Zip2Observable.scala Moves completion/error signaling to require external synchronization; updates async-ack completion path accordingly.
monix-reactive/shared/src/main/scala/monix/reactive/internal/builders/Zip3Observable.scala Shifts signalOnError/signalOnComplete synchronization responsibility to call-sites and updates subscribers.
monix-reactive/shared/src/main/scala/monix/reactive/internal/builders/Zip4Observable.scala Same synchronization-contract refactor and subscriber call-site updates.
monix-reactive/shared/src/main/scala/monix/reactive/internal/builders/Zip5Observable.scala Same synchronization-contract refactor and subscriber call-site updates.
monix-reactive/shared/src/main/scala/monix/reactive/internal/builders/Zip6Observable.scala Same synchronization-contract refactor and subscriber call-site updates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 64 to 67
val ack = out.onNext(c)
if (completeWithNext) {
ack.onComplete(_ => signalOnComplete(false))
ack.onComplete(_ => lock.synchronized(signalOnComplete(false)))
}
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adjusts the completion path to avoid re-entrant synchronization and relies on a specific ordering between downstream ack completion and the completeWithNext/signalOnComplete logic. There are Zip operator suites in monix-reactive/shared/src/test/scala/monix/reactive/internal/operators/Zip{2..6}Suite.scala, but none appear to exercise the completeWithNext/async-ack completion scenario; adding a regression test covering “one source completes after emitting while downstream onNext ack is async” would help prevent reintroducing the non-terminating behavior this PR is addressing.

Copilot uses AI. Check for mistakes.
…uilders/Zip5Observable.scala

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@alexandru alexandru enabled auto-merge (squash) April 27, 2026 08:54
@alexandru alexandru disabled auto-merge April 27, 2026 08:56
@alexandru alexandru merged commit 936ac33 into main Apr 27, 2026
13 checks passed
@alexandru alexandru deleted the fix-zip-observable-to-upstream branch April 27, 2026 08:57
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.

3 participants