Cascading reactive publisher for use with microservices or other computing environments

CN116420139BActive Publication Date: 2026-10-27ORACLE INT CORP
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202180072814.4
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Priority Date
2021-10-27
Filing Date
2021-10-28
Publication Date
2026-10-27
Estimated Expiration
2041-10-28

AI Technical Summary

Technical Problem

但是,由于在并发设置中重用值或对象,必须注意适应ABA问题,其中更新可能不会注意到值从A到B再返回到A的改变

Benefits of technology

[0010]状态的数量和过渡之间的协调是重要的,并且可能涉及错误条件和取消。所描述的方法通过允许系统将范围扩展到负值并通过使用原子请求计数器以维持需要的状态、注意背压并且当请求由拥有订阅的订阅者发布时尽快递送请求来支持将请求数量维持在至多Long.MAX_VALUE的要求,这减少了缓冲的需要。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN116420139B_ABST
    Figure CN116420139B_ABST
Patent Text Reader

Abstract

According to embodiments, described herein is a system and method for providing a cascading reactive publisher for use with microservices or reactive programming environments. The publisher provides a subscription to a subscriber that supports a number of requests up to a particular value. The publisher is able to keep track of the number of items requested. When cascading output from multiple publishers, the switching between the output of one publisher and the output of the next publisher can involve keeping track of a new state. The described method supports the requirement of maintaining a number of requests by using a request counter to maintain the required state, paying attention to back pressure, and delivering requests as soon as the subscriber that owns the subscription makes a request.
Need to check novelty before this filing date? Find Prior Art

Description

[0001] Copyright Notice

[0002] This patent document contains copyrighted material. The copyright holder does not object to any fax reproduction of the patent document or patent disclosure as it appears in the patent documents or records of the Patent and Trademark Office, but otherwise retains all copyright.

[0003] Priority Statement

[0004] This application claims priority to U.S. Provisional Application No. 63 / 108,143, filed October 30, 2020, entitled "CONSTANTMEMORY FOOTPRINT CONCATENATING REACTIVE PUBLISHER FOR USE WITH A MICROSERVICES OR OTHER COMPUTING ENVIRONMENT"; and U.S. Patent Application No. 17 / 512,319, filed October 27, 2021, entitled "CONCATENATING REACTIVE PUBLISHER FOR USE WITH A MICROSERVICES OR OTHER COMPUTING ENVIRONMENT"; each of the above applications and the contents thereof are incorporated herein by reference. Technical Field

[0005] The embodiments described herein generally relate to cloud computing and other computing environments, software development, microservice architectures, and reactive computing, and specifically to systems and methods for providing constant memory footprint cascaded reactive publishers in such environments. Background Technology

[0006] A microservices environment presents software applications as a loosely coupled collection of services that can be deployed independently and communicate with each other over a network. For example, the microservices approach can be used to develop software applications offered as cloud services in a cloud computing environment. In such environments, microservices can be used to provide resilience and efficiently utilize computing resources.

[0007] Reactive computing environments typically support publishers and subscribers using the onComplete signal. Such environments allow developers to declaratively construct pipelines and achieve high concurrency with a small number of threads, as the progress of computation can be controlled without resorting to blocking operations. However, due to the reuse of values ​​or objects in concurrent settings, care must be taken to accommodate the ABA problem, where updates may not notice changes in value from A to B and back to A. Summary of the Invention

[0008] According to embodiments, this document describes systems and methods for providing a constant memory footprint for use with microservices or reactive programming environments.

[0009] In one embodiment, the publisher offers a subscription to the subscriber, which supports a number of requests up to a specific value (Long.MAX_VALUE). The publisher can keep track of the requested number of items. When outputs from multiple publishers are cascaded, the switch between the outputs of one publisher and the output of the next publisher is not atomic and may involve keeping track of the new state, for example, when one publisher stops producing items and the next publisher has not yet started producing items.

[0010] Coordination between the number of states and transitions is important and may involve error conditions and cancellation. The described approach supports the requirement to keep the number of requests at most Long.MAX_VALUE by allowing the system to extend the range to negative values ​​and by using atomic request counters to maintain the required state, paying attention to backpressure, and delivering requests as soon as possible when they are published by subscribers who have a subscription, which reduces the need for buffering. Attached Figure Description

[0011] Figure 1 The illustration depicts an example microservice environment that provides a software development framework according to an embodiment.

[0012] Figure 2 The illustration depicts an example Helidon SE microservice environment according to an embodiment.

[0013] Figure 3 The illustration depicts an example Helidon MP microservice environment according to an embodiment.

[0014] Figure 4 The illustration depicts communication in a microservices environment according to an embodiment.

[0015] Figure 5 The illustration shows the use of a reactive environment in a microservices environment according to an embodiment.

[0016] Figure 6 The use of the reactive environment according to the embodiment is further illustrated.

[0017] Figure 7 The use of the reactive environment according to the embodiment is further illustrated.

[0018] Figure 8 The illustration depicts a system that provides a constant memory footprint for a cascading reactive publisher according to an embodiment.

[0019] Figure 9A system providing a constant memory footprint for a cascaded reactive publisher, according to an embodiment, is further illustrated.

[0020] Figure 10 An example of event handling according to an embodiment is illustrated.

[0021] Figure 11 An example of event handling according to an embodiment is illustrated.

[0022] Figure 12 An example of event handling according to an embodiment is illustrated.

[0023] Figure 13 An example of event handling according to an embodiment is illustrated.

[0024] Figure 14 An example of event handling according to an embodiment is illustrated.

[0025] Figure 15 An example of event handling according to an embodiment is illustrated.

[0026] Figure 16 The illustration depicts a process for providing a constant memory footprint for a cascaded reactive publisher according to an embodiment. Detailed Implementation

[0027] As mentioned above, a microservices architecture can present software applications as a loosely coupled collection of services that can be deployed independently and communicate with each other over a network. For example, the microservices approach can be used to develop software applications that are provided as cloud services in a cloud computing environment. In such an environment, microservices can be used to provide resilience and efficiently utilize computing resources.

[0028] Software development frameworks such as Helidon facilitate the development of microservices. For example, Helidon provides a Standard Edition (SE) and MicroProfile (MP) programming models or environments, each of which includes a collection of software libraries that support features such as configuration, security, or web server functionality; and provides software developers with the foundation for creating microservices.

[0029] In general, Helidon reduces the need for software developers to program according to specific tools or deployment models and allows microservices to run without an application server. The Helidon library can interoperate with other software development, deployment, and / or monitoring tools, such as Docker, Kubernetes, Prometheus, or OpenTracing.

[0030] Microservices Environment (Helidon)

[0031] Figure 1The illustration depicts an example microservice environment that provides a software development framework according to an embodiment.

[0032] like Figure 1 As shown, according to an embodiment, the Helidon microservice environment 100 provides a standard version (SE) and a microprofile (MP) programming model or environment.

[0033] According to an embodiment, the Helidon SE environment 110 may include various libraries, APIs, or other components, such as, for example, a reactive web server 111 that provides asynchronous and reactive APIs for creating web applications; a configuration API 112 that provides a Java API to load and process configuration attributes in key / value form into configuration objects, which applications can then use to retrieve configuration data; and a security component 113 that provides authentication, authorization, and outbound security; and may also include metrics 114, health checks 115, and tracking 116, or other components.

[0034] According to an embodiment, the Helidon MP environment 120 may include various libraries, APIs, or other components, such as, for example, JAX-RS 122, JSON-P 126, CDI 124, metrics 128, health checks 130, fault tolerance 132, MicroProfile configuration 134, and JWT authentication 136 components. According to an embodiment, the web server may be provided by a non-blocking client / server / web framework 118, such as Netty. The microservice environment can also enable interaction with the cloud, database, or other systems or services 140.

[0035] Figure 2 The illustration depicts an example Helidon SE microservice environment according to an embodiment.

[0036] like Figure 2 As shown in the examples, the Helidon SE environment supports a functional programming style that directly utilizes web servers, security, and configuration components; provides software developers with transparency and control; and supports Java features such as reactive streaming, asynchronous, and functional programming. The Helidon SE environment provides a framework through which software developers can build lightweight reactive microservices.

[0037] Figure 3 The illustration depicts an example Helidon MP microservice environment according to an embodiment.

[0038] like Figure 3As shown, according to an embodiment, the Helidon MP environment supports a declarative programming style by using a family of MicroProfiles for the API built on top of the Helidon library. MicroProfile definitions (e.g., specified by the Eclipse MicroProfile project) can be used to support application portability across multiple MicroProfile runtimes.

[0039] According to embodiments, a microservices environment can present software applications as a loosely coupled collection of services that can be deployed independently and communicate with each other over a network. For example, the Helidon microservices environment can support the use of remote procedure call (e.g., gRPC) frameworks or components, enabling (client and / or server) applications to communicate within the microservices environment to build connected systems.

[0040] Figure 4 The illustration depicts communication in a microservices environment according to an embodiment.

[0041] supply Figure 4 The examples shown and described are intended to illustrate one type of communication supported by a microservices environment; other types of communication may be supported according to other embodiments and examples.

[0042] like Figure 4 As shown, according to an embodiment, the Remote Procedure Call (RPC) framework enables the definition of services and methods that can be invoked remotely. A server or service can handle calls from a client via a local object (stub) at the client's location. This object allows the client application to directly invoke methods on the server application as if it were a local object. The server / service implements methods for handling client calls, including decoding the incoming request, executing the service method, and encoding the service response. The local object (stub) implements the same methods as the service, wrapping the parameters for the call in an appropriate protocol buffer message type and then providing it as a request to the server.

[0043] According to an embodiment, the microservice library enables client applications to access and communicate with microservices or interact with the cloud, database, or other systems or services to access data, process transactions, or perform other operations associated with those systems or services.

[0044] Reactive environment

[0045] In a traditional message-driven environment, the producer sends a message to the consumer when it becomes available; however, if the consumer cannot process the message in real time, the received message will be stored in a buffer, which can lead to performance issues.

[0046] According to embodiments, a microservice environment can provide a reactive environment, such as a reactive engine or reactive messaging API, for use with activities such as transaction processing, asynchronous messaging channels, or reactive streaming.

[0047] Figure 5 The illustration shows the use of a reactive environment in a microservices environment according to an embodiment.

[0048] supply Figure 5 The examples shown and described are examples of one type or use of reactive environments supported by microservice environments; other types and uses of reactive environments may be provided according to other embodiments and examples.

[0049] like Figure 5 As shown, according to an embodiment, reactive environment 200 enables client application 220 to communicate reactively with services acting as publishers and subscribers within a microservices environment. Connector 212 can be used to provide publishers and subscribers with access to reactive messaging channels, or to provide support for using reactive messaging with Kafka, JMS, or other types of messaging, message queuing, or stream processing environments.

[0050] Reactive environments enable asynchronous stream processing with non-blocking backpressure—subscribers inform publishers how much data they can process, and publishers send the appropriate amount of data according to the subscribers' requests.

[0051] Figure 6 The use of the reactive environment according to the embodiment is further illustrated.

[0052] like Figure 6 As shown, according to an embodiment, publisher 231 (referred to as publisher in some examples herein) operates as a producer of data based on the demands requested by its subscribers. Subscriber 232 (referred to as subscriber in some examples herein) operates as a consumer of the data produced by the publisher. Subscription (referred to as subscription in some examples herein) 234 defines the relationship between subscribers of a publisher and provides a mechanism for subscribers to request more data (from the publisher). According to an embodiment, a processor (referred to as processor in some examples herein) may be provided, which operates as a message / data processing stage and, via subscription, as both a subscriber and a publisher.

[0053] Figure 7 The use of the reactive environment according to the embodiment is further illustrated.

[0054] like Figure 7As shown in the example, when a subscriber is delivered to a publisher, the subscriber receives a call to the `onSubscribe(Subscription)` method but does not immediately begin receiving data items or other events. The subscriber only receives data items when it calls the `request(long)` method within its subscription, signaling to the publisher the need for more data. The subscriber can receive data by calling the `Subscriber.onNext` method, which is called with the next item and can be called multiple times (n), as determined by the length of the `request(long)` method passed to the subscriber. The `Subscriber.onError()` method can be called when an error occurs while processing the stream. The `Subscriber.onComplete()` method can be called when there is no more data to process. If both `onError()` and `onComplete()` events are called simultaneously, the publisher will not emit new data, even if the `request(long)` method is called again.

[0055] Constant memory usage of cascade reaction publishers

[0056] Modern software benefits from organizing computations in asynchronous pipelines with backpressure. This allows developers to construct pipelines declaratively and achieve high concurrency with a small number of threads—all thanks to the ability to control the progress of computation without resorting to blocking operations.

[0057] Reactive computing environments typically support the use of publishers and subscribers with the onComplete signal. Such environments allow developers to declaratively construct pipelines and achieve high concurrency with a small number of threads, as the progress of computation can be controlled without resorting to blocking operations. However, due to the reuse of values ​​or objects in concurrent settings, care must be taken to accommodate the ABA problem, where updates may not notice changes in value from A to B and back to A. Based on embodiments, this document describes systems and methods for providing a constant memory footprint for cascading reactive publishers for use with microservices or reactive programming environments.

[0058] For example, in reactive Java, asynchronous pipelines consist of publishers, subscribers, and processors. It is important to be able to construct pipelines that combine outputs from multiple publishers into a single, strictly ordered stream that conforms to the publisher API. This requires careful orchestration of state transitions and attention to backpressure from downstream components to ensure items arrive on time and remain stationary if downstream components are not ready. This is particularly difficult to achieve in a lock-free manner and even more so for constant (O(1)) memory footprints.

[0059] According to embodiments, this document describes systems and methods for providing a constant memory footprint for use with microservices or reactive programming environments.

[0060] In one embodiment, the publisher offers a subscription to the subscriber, which supports a number of requests up to a specific value (Long.MAX_VALUE). The publisher can keep track of the requested number of items. When outputs from multiple publishers are cascaded, the switch between the outputs of one publisher and the output of the next publisher is not atomic and may involve keeping track of the new state, for example, when one publisher stops producing items and the next publisher has not yet started producing items.

[0061] Coordination between the number of states and transitions is important and may involve error conditions and cancellation. The described approach supports the requirement to keep the number of requests at most Long.MAX_VALUE by allowing the system to extend the range to negative values ​​and by using atomic request counters to maintain the required state, paying attention to backpressure, and delivering requests as soon as possible when they are published by subscribers who have a subscription, which reduces the need for buffering.

[0062] According to embodiments, the technical advantages of the described method include, for example, minimizing memory footprint and points requiring coordination. Memory footprint is reduced by delegating all error condition management to internal publishers: as long as the internal publishers use it one after another, their onError signals can be simply forwarded downstream—no further coordination is required.

[0063] Figure 8 The illustration depicts a system that provides a constant memory footprint for a cascading reactive publisher according to an embodiment.

[0064] like Figure 8 As shown, according to an embodiment, and according to various embodiments, the system includes or operates a bounded recursive process 300 for use with an upstream publisher (publisher) 251 that publishes data items 260, 270, 280 via a plurality of internal publishers A 262, B ​​272, N 282, each internal publisher being associated with internal subscribers 264, 274, 284 respectively, and providing data as an event stream via internal subscribers 268, 278, 288 for use by a downstream subscriber (subscriber) 252.

[0065] As shown in the figure, the cascaded reactive publisher 240 can use a request counter 300, whose value 302 can be used to indicate a transition from the ABA and serve as a generation counter. The system also provides a pending counter 310, whose value 312 is used to track requests from downstream users. Both the pending and request counters can be in any of four states: BAD, CANCEL, SEE_OTHER, or INIT (count). The generation and request counts are combined to avoid creating new small objects and to account for memory usage.

[0066] Figure 9 A system providing a constant memory footprint for a cascaded reactive publisher, according to an embodiment, is further illustrated.

[0067] According to the embodiments, the described method enables the array of internal publishers to be exhausted sequentially, one after another. During this period, the system maintains tracking of requests from downstream entities and delegates most of the handling of transitions or errors to the internal publishers (in... Figure 10-15 (Indicated as 330, 340, 350), they operate on these transitions. This allows the system to avoid creating new objects and minimize communication between (one or more) internal publishers and downstream subscribers, thus maintaining a constant memory footprint, while also identifying those instances that can solve the ABA problem.

[0068] According to the embodiments, the described method provides an unbuffered component that conforms to the reactive Java publisher API and has O(1) memory footprint and is lock-free. Other methods using two counters may involve discarding one of the counters after disabling it and allocating a new counter to replace it (not a constant memory footprint), maintaining more state to resolve synchronization problems (such as the ABA problem), or making the state over-blocked (not lock-free). According to the embodiments, the described method supports the use of extended scopes to maintain additional state as needed.

[0069] According to the embodiment, it can be observed that the request counter does not decrease. The system can modify this condition so that the request counter always increases when switching from one publisher to the next. This requires expanding the request count to allow all possible requests from downstream, ranging from 0 to Long.MAX_VALUE. However, since there is no limit to the number of publishers cascaded in this way, the system can support cascading up to Long.MAX_VALUE-3 publishers without loss of accuracy. This additional range is used to continuously modify the request counter when a publisher stops producing items.

[0070] According to the embodiments, the described method supports distinguishing between two types of requests, which allow for guaranteeing one and only one delivery of good requests and at least one delivery of bad requests.

[0071] According to the implementation, it can be observed that even with the expanded range, subscribers may still issue enough requests, even exceeding the expanded range of the request counter. However, the system must accurately capture the request count only for good requests that do not exceed Long.MAX_VALUE.

[0072] Once that value is reached, the system doesn't need to pass good requests to any publisher, since we can always request MAX_VALUE. Meanwhile, bad requests are required to generate an onError event. This can be achieved by automatically transitioning from the current request count to a BAD request value and delivering that count to the current publisher. Unlike good requests, we're not limited to requesting only once, which allows us to discover the correct publisher that will deliver the onError event without resorting to additional state management. Typically, if an error is generated by an intermediate component, it needs to be tracked as additional state to ensure that one and only one onError event is delivered.

[0073] Solving the ABA problem in constant space

[0074] According to an embodiment, the ABA problem is the problem of reusing values ​​or objects in a concurrent setup, where atomic updates may not notice a change in value from A to B and back to A. In some cases, this can be solved by not reusing objects, so that the state never returns from B to A; however, this approach results in a new allocation over the lifetime of the program.

[0075] In this embodiment, objects are reused to keep memory usage constant. The ABA problem is solved by ensuring that the transition from B to A only occurs under carefully managed, benign conditions. This can be achieved by monotonically incrementing the requested counter, so that concurrent updates of the counter do not miss other updates. However, this is insufficient in this scenario because several other conditions need to be tracked, such as: subscription cancellation; error conditions signaled by the internal publisher; invalid requests from downstream subscribers; and switching from one internal subscription to another.

[0076] In addition, in the presence of internal publishers, it is necessary to track how many requests from downstream subscribers the current internal publisher has not yet fulfilled, so that the unfulfilled amount can be requested from the next internal publisher when it is ready.

[0077] A complex aspect of the reactive specification is the requirement to handle invalid requests from downstream subscribers by generating an `onError` signal. While it's easy to simply delegate invalid requests to an internal publisher when it's ready, this becomes impossible when switching from one internal subscription to another—sometimes the current internal subscription is terminated, and the new internal subscription hasn't arrived from the next internal publisher. If a cascading publisher is to emit its own `onError` event, it must ensure that these events are correctly serialized relative to any other signals that an internal publisher might emit, that no further signals are forwarded to downstream subscribers after the `onError` event is signaled, and that any unterminated subscriptions are canceled. According to the method described in this paper, this is addressed by delegating invalid requests to the next internal publisher.

[0078] According to the embodiment, by choosing to delegate all requests and undelegates to internal publishers and forward all signals to downstream subscribers, it is necessary to ensure backpressure when switching from one internal subscription to the next: that is, all internal publishers that are treated as a single onNext signal stream by downstream subscribers no longer emit onNext events because the subscribers have issued valid requests. This requires shifting the number of requests sent to one internal publisher to the next, minus the number of requests already satisfied; and this should be implemented without atomic state transitions.

[0079] According to the embodiment, the system can observe that each internal subscription is in one of the following states:

[0080] It is safe to make a request to it.

[0081] It is safe to make requests to it, and it is also safe to transfer them to the next internal publisher.

[0082] Sending a request to it is safe, but it's futile—the request must be passed on to the next internal publisher.

[0083] Sending a request to it is safe, but it's futile—the new request has no further impact on the signals observed by downstream subscribers.

[0084] The following conditions can be observed to hold generally: if we cannot prove that a subscription has terminated, then we should send a request to a subscription that existed before the request counter was atomically updated—this is to ensure that the signal is delivered "at most once"; if we cannot prove that a subscription will observe the request and deliver the signal, then we should send a request to a subscription that existed after the request counter was atomically updated—this is to ensure that the signal is delivered "at least once".

[0085] According to the embodiment, the first method is used to ensure that double billing does not occur and to take precautions against back pressure. When a subscription reaches its termination state, the situation needs to be checked, and any unfulfilled requests should be transferred to the next internal subscription if it is still safe to do so.

[0086] According to the embodiment, a second method is used to ensure the propagation of cancellation and error signals caused by invalid requests. It is safe to issue multiple cancellation or invalid requests to any internal subscription—allowing concurrent cancellations, requests, and other routines that might observe this state ensures that delivering these signals to the current or any other internal subscription is safe—issuing these signals does not result in multiple onErrors or any other termination state (e.g., quiescent).

[0087] According to an embodiment, the distinction between the two methods can be achieved through the following collaboration:

[0088] onSubscribe — Published by an internal publisher to signal that it is ready to be served for internal subscriptions.

[0089] onComplete—is signaled by the internal publisher when an internal subscription has reached the termination state program order between onComplete of an internal subscription and the next concurrent call to onSubscribe from request() or cancel().

[0090] According to an embodiment, this is performed by managing two atomic counters: a request counter and a pending counter.

[0091] The `onComplete` method sets both the request and pending counters to a state where either can be safely updated: the request counter is already in this state, and the pending counter is set to the number of requests that have been satisfied—this number will not be modified concurrently because the internal subscription has reached a termination state.

[0092] The onComplete method atomically sets the request counter to the SEE_OTHER state, which requires concurrent request() calls to update only the pending counter.

[0093] The onComplete function automatically updates the pending counter with the number of unfulfilled requests—this is calculated based on the value of the request counter and the number of requests that have been fulfilled.

[0094] If any concurrent request() calls occur before the request counter is set to the SEE_OTHER state, which requires them to update the pending counter, then they will update the request counter and issue requests to subscriptions known to be in a state where they will no longer generate any signals. Therefore, it is safe to move the number of requests to the pending counter later.

[0095] According to the implementation, if any concurrent request() calls occur after the request counter is set to the SEE_OTHER state but before the next onSubscribe, they will update the pending counter and will not interact with any internal subscription. The atomic update to the pending counter later by onComplete tracks unfulfilled requests and these concurrent requests.

[0096] According to the embodiments, the described method is characterized by handling pending and request counters via onSubscribe. Although the operation performed is actually the opposite of what onComplete is performing—copying the pending counter to the request counter—it is performed in a slightly different manner, the reason for which will become apparent later when discussing the ABA problem.

[0097] The onSubscribe option sets up a new internal subscription.

[0098] The onSubscribe option sets the request and pending counters to a state where either one can be safely updated: the pending counter is already in this state, and the request counter is set to the current value of the pending counter.

[0099] onSubscribe atomically sets the pending counter to the SEE_OTHER state, which requires concurrent request() calls to update only the request counter and issue request() calls on the current internal subscription.

[0100] If any concurrent updates to the pending counter are made between setting the request counter to the SEE_OTHER state and setting the pending counter to the SEE_OTHER state, then onSubscribe updates the request counter.

[0101] onSubscribe sends unfulfilled requests to the internal subscription—calculated based on the status of a pending counter and the number of previously fulfilled requests—this counter is not updated concurrently because the internal publisher cannot issue onNext before onSubscribe completes.

[0102] If any concurrent calls to `request()` occur before the request counter is set to the pending counter, they will update the pending counter and not interact with any internal subscription. Therefore, it is safe to transfer the number of pending requests to the requested counter and call the internal subscription's `request()`.

[0103] According to the implementation, if any concurrent calls to `request()` occur after the request counter has been set to the value of the pending counter, they will update the request counter and issue a request directly to the current internal subscription. No special tracking of these is required. However, it's important to note that the ABA problem can occur in this case if the request counter is not properly managed.

[0104] Specifically, if the request counter is set to SEE_OTHER by onComplete, and then onSubscribe returns to the same value seen by onComplete (temporarily stored in a pending counter), then a concurrent request() call will observe the inner subscription calling request() before the request counter is updated. This could be an inner subscription that existed before onComplete completes. Such a request cannot be satisfied by that inner subscription, and downstream subscribers can interpret this as a lack of progress.

[0105] According to the implementation, when an internal subscription changes, the system can ensure that the value of the request counter is not the same. This is done by manually incrementing the request counter via onComplete and the counter for satisfied requests via onSubscribe, to keep the backpressure the same as before onComplete.

[0106] In addition, the system can maintain the same range of available backpressure by extending the request counter range from 0 to the desired range of Long.MAX_VALUE by almost doubling it, by starting the request counter from INIT, which is Long.MAX_VALUE + 3 – therefore the publisher must handle the onComplete INIT time before downstream subscribers can detect the lack of available backpressure. This is impossible to achieve in modern physical systems; even reactive specifications treat Long.MAX_VALUE as practically infinite.

[0107] If a concurrent `request()` call attempts to issue an invalid request, the ABA problem may still occur, and a benign race condition may arise. If a new internal subscription is set up after `onSubscribe` has already set a request counter, this concurrent `request()` call will observe the already set internal subscription and forward the invalid request to it, which will eventually lead to an `onError` signal. Alternatively, if the subscription is already terminated, it will lead to `onComplete`, which will simply preserve the request counter's state until the next `onSubscribe` call. `onSubscribe` will not observe the concurrent `request()` call issuing invalid requests and will issue some valid requests that have not yet been satisfied. This cannot create more events than the reactive specification allows.

[0108] According to the embodiments, it can be observed that the expansion of the request counter range allows changes to the internal subscription to be detected only when the counter reaches Long.MAX_VALUE. Although the range is expanded, this is possible - downstream subscribers are not obligated to stop issuing request() when any particular level of backpressure is reached, and may even exceed the expanded range - for example, by making more than one request for Long.MAX_VALUE.

[0109] In this state, the ABA problem reappears – the request counter can be observed to change from Long.MAX_VALUE to SEE_OTHER, and then back to Long.MAX_VALUE – and concurrent calls to request() will not detect this because the counter cannot continue to increment beyond Long.MAX_VALUE. However, the proposed design ensures that the ABA problem is benign in this case, as explained below.

[0110] According to the implementation, when concurrent request() cannot observe changes in the internal subscription, it issues request() on the wrong internal subscription—one that has already reached its termination state. However, this does not result in a loss of backpressure level when a valid request is issued. The ABA problem only occurs when onSubscribe follows onComplete. Even if concurrent requests can issue request() on a quiescent internal subscription, onSubscribe will observe that the request counter is already at Long.MAX_VALUE and will issue a Long.MAX_VALUE request on the new internal subscription, thus preserving the correct backpressure level.

[0111] Event handling

[0112] Figure 10-15 Various examples of event handling according to embodiments are illustrated.

[0113] According to an embodiment, for example, Figure 10 The diagram illustrates that the ABA problem does occur, but in a benign environment: onSubscribe issues a request to maintain the correct back pressure, and issuing request() on the quiescent internal subscription "sub1" does not generate new events.

[0114] Figure 11 The illustration shows a second scenario where concurrent request() fails to observe changes to the internal subscription: when a downstream subscriber delivers an invalid request after reaching Long.MAX_VALUE. In this case, onSubscribe might issue a Long.MAX_VALUE request to the new internal subscription, but if it follows the normal request process, concurrent request() can update the request counter and issue a request() to the old (static) internal subscription that it observed before updating the request counter.

[0115] According to an embodiment, Figure 11 The diagram illustrates an environment where concurrent `cancel()` or `request()` calls might fail to observe changes to the internal subscription, and if it conforms to the good `request()` protocol, this could lead to a violation of the reactive publisher specification's cancellation or error notification requirements, signaling these events on `sub1` before the request counter is updated. Instead, in this design, these specific conditions follow a different path: when a cancellation or invalid request is made, these calls are emitted by the internal subscription observed after the atomic update of the request counter.

[0116] According to various embodiments, possible event interleaving may include, for example:

[0117] like Figure 12 As shown in the figure, the system issues a cancellation or invalidation request for a static internal subscription.

[0118] like Figure 13 As shown in the figure, the system issued two cancellation or invalidation requests for the same internal subscription.

[0119] like Figure 14 As shown, the system concurrently issues cancellation or invalidation requests with onSubscribe.

[0120] According to an embodiment, Figure 15The diagram illustrates an environment where concurrent calls to request() will be able to detect changes to internal subscriptions if the request counter is updated for each new internal subscription. Consequently, they will either issue request() to an internal subscription known to be in a terminated state (safely transferring the request to the next internal publisher) or observe a new internal subscription (the routine that sets up the new subscription can detect this update to the request counter without needing to transfer it).

[0121] Figure 16 The illustration depicts a process for providing a constant memory footprint for a cascaded reactive publisher according to an embodiment.

[0122] like Figure 16 As shown, according to an embodiment, at step 360, a computer including one or more processors and memory, as well as a microservice environment (microservice library), provides a reactive environment that can be used with reactive streams to enable client and server applications to communicate within the microservice environment.

[0123] At step 362, multiple publishers and subscribers are provided in the reactive environment, wherein onSubscribe can be emitted by an internal publisher to signal that it is ready to serve an internal subscription; and wherein an internal publisher can emit onComplete to signal that a termination state is reached between onComplete when the internal subscription has been internally subscribed and onSubscribe when request() or cancel() is called again concurrently.

[0124] At step 364, a request counter and a pending counter for storing values ​​are provided in association with the cascading reaction publisher, wherein:

[0125] At step 366, OnComplete sets the request counter and the pending counter to a state that can be safely updated, including the request counter already being in this state and the pending counter being set to the number of requests that have been satisfied.

[0126] At step 368, onComplete atomically sets the request counter to the SEE_OTHER state, which requires concurrent request() calls to update only the pending counter.

[0127] At step 370, onComplete atomically updates the pending counter with the number of unfulfilled requests, which is calculated based on the value of the request counter and the number of fulfilled requests.

[0128] At step 372, the reactive environment processes requests from multiple internal publishing sites to deliver data to downstream subscribers.

[0129] According to various embodiments, aspects of this disclosure may include, for example:

[0130] According to an embodiment, a system for providing a constant memory footprint for cascading reactive publishers, for use with microservices or reactive programming environments, includes:

[0131] A computer, including one or more processors, provides access to microservices or other computing environments for use with software applications;

[0132] The publisher provides subscriptions to subscribers, which support a maximum number of requests up to a specified value; and

[0133] The system is adapted to extend the scope of requests, along with using request counters to maintain the necessary state and deliver requests when they are made by subscribers who have a subscription.

[0134] According to an embodiment, a method for providing a constant memory footprint for cascading reactive publishers, for use with microservices or reactive programming environments, includes:

[0135] To provide microservices or other computing environments on a computer that includes one or more processors for use with software applications;

[0136] The publisher provides subscriptions to subscribers, which support a maximum number of requests up to a specified value; and

[0137] Extend the request scope, along with using request counters to maintain the necessary state and deliver requests when they are made by subscribers who have a subscription.

[0138] According to an embodiment, a non-transitory computer-readable storage medium includes instructions stored thereon, which, when read and executed by one or more computers, cause the one or more computers to perform steps, including:

[0139] To provide microservices or other computing environments on a computer that includes one or more processors for use with software applications;

[0140] The publisher provides subscriptions to subscribers, which support a maximum number of requests up to a specified value; and

[0141] Extend the request scope, along with using request counters to maintain the necessary state and deliver requests when they are made by subscribers who have a subscription.

[0142] According to various embodiments, the teachings herein can be conveniently implemented using one or more conventional general-purpose or special-purpose computers, computing devices, machines, or microprocessors (including one or more processors, memory, and / or computer-readable storage media programmed according to the teachings of this disclosure). As will be apparent to those skilled in the art of software, a skilled programmer can readily prepare appropriate software code based on the teachings of this disclosure.

[0143] In some embodiments, the teachings herein may include a computer program product, which is one or more non-transitory computer-readable storage media on which / therein stores instructions that can be used to program a computer to perform any of the processing described herein. Examples of such storage media may include, but are not limited to, hard disk drives, hard drives, fixed disks or other electromechanical data storage devices, floppy disks, optical disks, DVDs, CD-ROMs, microdrives and magneto-optical disks, ROMs, RAMs, EPROMs, EEPROMs, DRAMs, VRAMs, flash memory devices, magnetic cards or optical cards, nanosystems or other types of storage media or devices suitable for the non-transitory storage of instructions and / or data.

[0144] The foregoing description is provided for illustrative purposes. It is not intended to be exhaustive or to limit the scope of protection to the precise forms disclosed. Many modifications and variations will be apparent to those skilled in the art.

[0145] For example, while various embodiments of the systems and methods described herein illustrate use in the Helidon microservices environment, these embodiments can be used with other types of microservices environments or other computing environments.

[0146] The embodiments were chosen and described in order to best explain the principles of this teaching and its practical application, thereby enabling others skilled in the art to understand the various embodiments and modifications suitable for the particular intended use. The scope is intended to be defined by the appended claims and their equivalents.

Claims

1. A system for use with a reactive computing environment for providing cascaded reactive publishers with constant memory footprint, comprising: A computer, including one or more processors, that provides a reactive environment for use with microservices and software applications, supporting the use of publishers, subscribers, and on-complete signals. In this system, publishers provide subscriptions to downstream subscribers, and these subscriptions support a maximum number of requests, including instances where upstream publishers publish data items via multiple internal publishers. Each of the plurality of internal publishers is associated with an internal subscriber. Each internal publisher provides its data via an internal subscription. The aforementioned multiple internal publisher operations are used to provide data items as an event stream to downstream subscribers; and The system described herein is adapted to use a request counter to maintain state and deliver requests when they are made by subscribers who have a subscription, including The request counter is stored and updated to indicate the value of the transition between the output of the first internal publisher and the output of the second internal publisher when providing its data. The pending counter is updated to indicate the number of requests from downstream subscribers.

2. The system of claim 1 further includes extending the request scope in conjunction with the use of a request counter to maintain state and deliver requests when they are made by downstream subscribers who have a subscription.

3. The system of claim 1, wherein the value of the request counter is used by the system to indicate the transition between the plurality of internal publishers, and wherein the value of the pending counter is used by the system to keep track of requests from downstream subscribers.

4. The system of claim 1, wherein the reactive environment enables client software applications to communicate reactively with services as publishers and subscribers within a microservices environment.

5. The system of claim 1, wherein a reactive environment is provided within a cloud computing environment that provides access to one or more clouds, databases or other systems or services.

6. A method for use with a reactive computing environment to provide a cascaded reactive publisher with constant memory footprint, comprising: A reactive environment on a computer that includes one or more processors, providing support for publishers, subscribers, and on-complete signals for use with microservices and software applications; In this system, publishers provide subscriptions to downstream subscribers, and these subscriptions support a maximum number of requests, including instances where upstream publishers publish data items via multiple internal publishers. Each of the plurality of internal publishers is associated with an internal subscriber. Each internal publisher provides its data via an internal subscription. The aforementioned multiple internal publishers operate to provide data items as an event stream for use by downstream subscribers; as well as Use a request counter to maintain state and deliver requests when they are made by subscribers who have a subscription, including The request counter is stored and updated to indicate the value of the transition between the output of the first internal publisher and the output of the second internal publisher when providing its data. The pending counter is updated to indicate the number of requests from downstream subscribers.

7. The method of claim 6, further comprising extending the request scope in conjunction with the use of a request counter to maintain state and deliver requests when they are made by downstream subscribers who have a subscription.

8. The method of claim 6, further comprising using the value of a request counter to indicate a transition between the plurality of internal publishers, and using the value of a pending counter to track requests from downstream subscribers.

9. The method of claim 6, wherein the reactive environment enables client software applications to communicate reactively with services as publishers and subscribers within a microservices environment.

10. The method of claim 6, wherein a reactive environment is provided within a cloud computing environment that provides access to one or more clouds, databases, or other systems or services.

11. A non-transitory computer-readable storage medium comprising instructions stored thereon, the instructions causing the one or more computers to perform steps when read and executed by the one or more computers, the steps comprising: A reactive environment on a computer that includes one or more processors, providing support for publishers, subscribers, and on-complete signals for use with microservices and software applications; In this system, publishers provide subscriptions to downstream subscribers, and these subscriptions support a maximum number of requests, including instances where upstream publishers publish data items via multiple internal publishers. Each of the plurality of internal publishers is associated with an internal subscriber. Each internal publisher provides its data via an internal subscription. The aforementioned multiple internal publishers operate to provide data items as an event stream for use by downstream subscribers; as well as Use a request counter to maintain state and deliver requests when they are made by subscribers who have a subscription, including The request counter is stored and updated to indicate the value of the transition between the output of the first internal publisher and the output of the second internal publisher when providing its data. The pending counter is updated to indicate the number of requests from downstream subscribers.

12. The non-transitory computer-readable storage medium of claim 11, further comprising extending the request scope in conjunction with the use of a request counter to maintain state and deliver requests when they are made by downstream subscribers who have a subscription.

13. The non-transitory computer-readable storage medium of claim 11, further comprising using the value of a request counter to indicate a transition between the plurality of internal publishers, and using the value of a pending counter to track requests from downstream subscribers.

14. The non-transitory computer-readable storage medium of claim 11, wherein the reactive environment enables client software applications to communicate reactively with services as publishers and subscribers within a microservices environment.

15. The non-transitory computer-readable storage medium of claim 11, wherein a reactive environment is provided within a cloud computing environment that provides access to one or more clouds, databases or other systems or services.

Citation Information

Patent Citations

  • Control of publish / subscribe messaging

    US20060047666A1

  • Systems and Methods for Controlling Retention of Publication

    US20110099232A1