From 50949ccec4bdce4c440c5efc2c4e9689cb833cc0 Mon Sep 17 00:00:00 2001 From: Dave Moten Date: Sat, 8 Dec 2018 08:59:38 +1100 Subject: [PATCH 1/5] improve Publisher 1.3 #431 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ac99caa..991d58c2 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,8 @@ public interface Publisher { | [:bulb:](#1.1 "1.1 explained") | *The intent of this rule is to make it clear that Publishers cannot signal more elements than Subscribers have requested. There’s an implicit, but important, consequence to this rule: Since demand can only be fulfilled after it has been received, there’s a happens-before relationship between requesting elements and receiving elements.* | | 2 | A `Publisher` MAY signal fewer `onNext` than requested and terminate the `Subscription` by calling `onComplete` or `onError`. | | [:bulb:](#1.2 "1.2 explained") | *The intent of this rule is to make it clear that a Publisher cannot guarantee that it will be able to produce the number of elements requested; it simply might not be able to produce them all; it may be in a failed state; it may be empty or otherwise already completed.* | -| 3 | `onSubscribe`, `onNext`, `onError` and `onComplete` signaled to a `Subscriber` MUST be signaled in a [thread-safe](#term_thread-safe) manner—and if performed by multiple threads—use [external synchronization](#term_ext_sync). | -| [:bulb:](#1.3 "1.3 explained") | *The intent of this rule is to make it clear that [external synchronization](#term_ext_sync) must be employed if the Publisher intends to send signals from multiple/different threads.* | +| 3 | `onSubscribe`, `onNext`, `onError` and `onComplete` signaled to a `Subscriber` MUST be signaled serially. | +| [:bulb:](#1.3 "1.3 explained") | *The intent of this rule is to permit the signalling of signals from multiple threads if and only if a happens-before relation between each of the signals is established.* | | 4 | If a `Publisher` fails it MUST signal an `onError`. | | [:bulb:](#1.4 "1.4 explained") | *The intent of this rule is to make it clear that a Publisher is responsible for notifying its Subscribers if it detects that it cannot proceed—Subscribers must be given a chance to clean up resources or otherwise deal with the Publisher´s failures.* | | 5 | If a `Publisher` terminates successfully (finite stream) it MUST signal an `onComplete`. | From e86fbb91651dd65986e1dd45c0f1b709086c3d9b Mon Sep 17 00:00:00 2001 From: Dave Moten Date: Tue, 22 Jan 2019 15:51:06 +1100 Subject: [PATCH 2/5] add Serially glossary entry --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 991d58c2..e8233fd0 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ followed by a possibly unbounded number of `onNext` signals (as requested by `Su | NOP | Execution that has no detectable effect to the calling thread, and can as such safely be called any number of times.| | External synchronization | Access coordination for thread safety purposes implemented outside of the constructs defined in this specification, using techniques such as, but not limited to, `atomics`, `monitors`, or `locks`. | | Thread-safe | Can be safely invoked synchronously, or asychronously, without requiring external synchronization to ensure program correctness. | +| Serial(ly) | In the context of a [Signal](#term_signal), are non-overlapping. In the context of the JVM, calls to methods on an object are serial if and only if there is a happens-before relationship between those calls. This is the case if they are called [Synchronously](#term_sync), but when performed asynchronously, coordination to establish the happens-before relationship (which ensures the calls do not overlap) is to be implemented using techniques such as, but not limited to, atomics, monitors, or locks. | +| 8 | A `Subscriber` MUST be prepared to receive one or more `onNext` signals after having called `Subscription.cancel()` if there are still requested elements pending [see [3.12](#3.12)]. `Subscription.cancel()` does not guarantee to perform the underlying cleaning operations immediately. | | [:bulb:](#2.8 "2.8 explained") | *The intent of this rule is to highlight that there may be a delay between calling `cancel` and the Publisher observing that cancellation.* | | 9 | A `Subscriber` MUST be prepared to receive an `onComplete` signal with or without a preceding `Subscription.request(long n)` call. | From be8af7d86e4cdd58ebc17e062c1d7e2680c33184 Mon Sep 17 00:00:00 2001 From: Dave Moten Date: Tue, 22 Jan 2019 16:24:07 +1100 Subject: [PATCH 4/5] update 2.7 intent --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6a07642..116100de 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ public interface Subscriber { | 6 | A `Subscriber` MUST call `Subscription.cancel()` if the `Subscription` is no longer needed. | | [:bulb:](#2.6 "2.6 explained") | *The intent of this rule is to establish that Subscribers cannot just throw Subscriptions away when they are no longer needed, they have to call `cancel` so that resources held by that Subscription can be safely, and timely, reclaimed. An example of this would be a Subscriber which is only interested in a specific element, which would then cancel its Subscription to signal its completion to the Publisher.* | | 7 | A Subscriber MUST ensure that all calls on its Subscription's request and cancel methods are performed [serially](#term_serially). | -| [:bulb:](#2.7 "2.7 explained") | *The intent of this rule is TODO.* | +| [:bulb:](#2.7 "2.7 explained") | *The intent of this rule is to permit the calling of the request and cancel methods if and only if a happens-before relation between each of the calls is established..* | | 8 | A `Subscriber` MUST be prepared to receive one or more `onNext` signals after having called `Subscription.cancel()` if there are still requested elements pending [see [3.12](#3.12)]. `Subscription.cancel()` does not guarantee to perform the underlying cleaning operations immediately. | | [:bulb:](#2.8 "2.8 explained") | *The intent of this rule is to highlight that there may be a delay between calling `cancel` and the Publisher observing that cancellation.* | | 9 | A `Subscriber` MUST be prepared to receive an `onComplete` signal with or without a preceding `Subscription.request(long n)` call. | From 556d9ffcc3c995ecbb1483d7d514c6ef755bfcd5 Mon Sep 17 00:00:00 2001 From: Dave Moten Date: Tue, 22 Jan 2019 16:27:26 +1100 Subject: [PATCH 5/5] update because happens-before applicable in single thread for preventing re-entrancy --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 116100de..f017821c 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ public interface Publisher { | 2 | A `Publisher` MAY signal fewer `onNext` than requested and terminate the `Subscription` by calling `onComplete` or `onError`. | | [:bulb:](#1.2 "1.2 explained") | *The intent of this rule is to make it clear that a Publisher cannot guarantee that it will be able to produce the number of elements requested; it simply might not be able to produce them all; it may be in a failed state; it may be empty or otherwise already completed.* | | 3 | `onSubscribe`, `onNext`, `onError` and `onComplete` signaled to a `Subscriber` MUST be signaled [serially](#term_serially). | -| [:bulb:](#1.3 "1.3 explained") | *The intent of this rule is to permit the signalling of signals from multiple threads if and only if a happens-before relation between each of the signals is established.* | +| [:bulb:](#1.3 "1.3 explained") | *The intent of this rule is to permit the signalling of signals (including from multiple threads) if and only if a happens-before relation between each of the signals is established.* | | 4 | If a `Publisher` fails it MUST signal an `onError`. | | [:bulb:](#1.4 "1.4 explained") | *The intent of this rule is to make it clear that a Publisher is responsible for notifying its Subscribers if it detects that it cannot proceed—Subscribers must be given a chance to clean up resources or otherwise deal with the Publisher´s failures.* | | 5 | If a `Publisher` terminates successfully (finite stream) it MUST signal an `onComplete`. | @@ -142,7 +142,7 @@ public interface Subscriber { | 6 | A `Subscriber` MUST call `Subscription.cancel()` if the `Subscription` is no longer needed. | | [:bulb:](#2.6 "2.6 explained") | *The intent of this rule is to establish that Subscribers cannot just throw Subscriptions away when they are no longer needed, they have to call `cancel` so that resources held by that Subscription can be safely, and timely, reclaimed. An example of this would be a Subscriber which is only interested in a specific element, which would then cancel its Subscription to signal its completion to the Publisher.* | | 7 | A Subscriber MUST ensure that all calls on its Subscription's request and cancel methods are performed [serially](#term_serially). | -| [:bulb:](#2.7 "2.7 explained") | *The intent of this rule is to permit the calling of the request and cancel methods if and only if a happens-before relation between each of the calls is established..* | +| [:bulb:](#2.7 "2.7 explained") | *The intent of this rule is to permit the calling of the request and cancel methods (including from multiple threads) if and only if a happens-before relation between each of the calls is established..* | | 8 | A `Subscriber` MUST be prepared to receive one or more `onNext` signals after having called `Subscription.cancel()` if there are still requested elements pending [see [3.12](#3.12)]. `Subscription.cancel()` does not guarantee to perform the underlying cleaning operations immediately. | | [:bulb:](#2.8 "2.8 explained") | *The intent of this rule is to highlight that there may be a delay between calling `cancel` and the Publisher observing that cancellation.* | | 9 | A `Subscriber` MUST be prepared to receive an `onComplete` signal with or without a preceding `Subscription.request(long n)` call. |