Process output fan-out method and apparatus

CN122903221APending Publication Date: 2026-10-13BEIJING JILIU TECH CO LTD
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202611359254.1
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2026-09-03
Publication Date
2026-10-13

AI Technical Summary

Technical Problem

然而,在云沙箱暂停后恢复的过程中,暂停前建立的部分客户端连接可能已经断开,但相应订阅关系仍然存在,从而形成无法正常接收输出事件的僵尸订阅者

Benefits of technology

[0016]本申请提供的进程输出扇出方法及装置,通过获取目标进程的输出事件,并遍历订阅目标进程的各订阅者,使得该方法及装置实现了分别对各订阅者执行对应的输出事件处理;再通过在目标订阅者处于取消状态的情况下跳过目标订阅者,使得该方法及装置实现了避免执行无效的输出事件投递,并使当前输出事件的扇出过程能够继续处理其他未处于取消状态的目标订阅者;再通过在目标订阅者未处于取消状态,且目标私有通道的缓冲区未满的情况下,将输出事件投递至目标私有通道,使得该方法及装置实现了利用目标私有通道的缓冲空间暂时存储尚未被目标订阅者消费的输出事件,从而使健康但暂时处理较慢的目标订阅者无需立即完成每一个输出事件的消费,容忍一定程度的瞬时流量突发或者短时间消费速度波动;再通过在目标订阅者未处于取消状态,且目标私有通道的缓冲区已满的情况下,将目标订阅者设置为取消状态,使得该方法及装置实现了在僵尸订阅者或者极慢订阅者无法及时消费输出事件时,不再持续等待缓冲空间,从而降低异常订阅者对进程输出扇出过程的影响,避免单个异常订阅者阻塞其他订阅者的输出事件接收,提升进程输出扇出的实时性和稳定性。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122903221A_ABST
    Figure CN122903221A_ABST
Patent Text Reader

Abstract

The application relates to the technical field of computer processing, and provides a process output fan-out method and device. The method comprises the following steps: obtaining an output event of a target process; traversing each subscriber subscribing to the target process; for any subscriber traversed, determining that the any subscriber is a target subscriber; in the case that the target subscriber is in a cancel state, skipping the target subscriber; in the case that the target subscriber is not in the cancel state and a buffer area of a target private channel of the target subscriber is not full, delivering the output event to the target private channel; and in the case that the target subscriber is not in the cancel state and the buffer area of the target private channel of the target subscriber is full, setting the target subscriber to the cancel state. The process output fan-out method and device provided by the application improve the real-time performance and stability of process output fan-out.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This application relates to the field of computer processing technology, and in particular to a process output fan-out method and apparatus. Background Technology

[0002] In a cloud sandbox system, standard output and standard errors generated during the execution of user processes typically need to be pushed to multiple concurrent clients, such as integrated development environment plugins, command-line tools, and monitoring systems.

[0003] Cloud sandboxes typically support pause and resume operations. However, during the resumption process after a pause in a cloud sandbox, some client connections established before the pause may have been lost, but the corresponding subscription relationships still exist, creating zombie subscribers that cannot receive output events normally. When a fan-out goroutine delivers output events to a zombie subscriber, the delivery of output events may be blocked for a long time due to the unbuffered nature of the existing private channels, thus blocking the entire fan-out process and preventing other subscribers that can normally receive output events from the target process from obtaining them in a timely manner.

[0004] Therefore, how to reduce the impact of abnormal subscribers on the process output fan-out process, avoid a single abnormal subscriber blocking the reception of output events of other subscribers, and improve the real-time performance and stability of process output fan-out are technical problems that urgently need to be solved. Summary of the Invention

[0005] This application provides a process output fan-out method and apparatus to reduce the impact of abnormal subscribers on the process output fan-out process, avoid a single abnormal subscriber blocking the output event reception of other subscribers, and improve the real-time performance and stability of process output fan-out.

[0006] Firstly, this application provides a process output fan-out method, the method comprising: Obtain the output events of the target process; Iterate through all subscribers to the target process, and for any subscriber encountered, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

[0007] Optionally, according to the process output fan-out method of this application, setting the target subscriber to an unsubscribed state includes: Close the cancellation instruction channel associated with the target subscriber; the closed status of the cancellation instruction channel indicates that the target subscriber is in a canceled state; Close the target private channel of the target subscriber, and exit the event reading loop for the target private channel when the consuming coroutine detects that the target private channel is closed.

[0008] Optionally, according to the process output fan-out method of this application, the step of traversing each subscriber subscribing to the target process includes: Add a read lock to the subscriber list used to record each subscriber, and obtain the subscriber snapshot corresponding to the subscriber list; Release the read lock; Iterate through each subscriber based on the subscriber snapshot.

[0009] Optionally, according to the process output fan-out method of this application, the method further includes at least one of the following: In the case of canceling the target subscriber, the target subscriber is set to the canceled state; a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the target subscriber is removed from the subscriber list; When a new subscriber is registered, the source channel corresponding to the target process is obtained, and the closed status of the source channel is checked for the first time. If the first check determines that the source channel is not closed, a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the closed status of the source channel is checked for the second time. If the second check determines that the source channel is not closed, the new subscriber is added to the subscriber list. If the first or second check determines that the source channel is closed, the pre-closed private channel is returned to the caller corresponding to the new subscriber.

[0010] Optionally, according to the process output fan-out method of this application, the method further includes: Maintain the subscriber status of each subscriber; the subscriber status includes an active state, a canceled state, and a channel closed state that change sequentially in one direction. If the target subscriber is canceled, the subscriber status of the target subscriber will be updated from active to canceled. If the target private channel is closed, the subscriber status of the target subscriber will be updated from canceled to closed. If the target subscriber is in a closed channel state, stop delivering output events to the target private channel.

[0011] Optionally, according to the process output fan-out method of this application, the method further includes: Configure a single-execution control component corresponding to the target subscriber; The single-execution control component controls the target number of operations to close the cancellation instruction channel and close the target private channel.

[0012] Optionally, according to the process output fan-out method of this application, the buffer capacity of the target private channel is a fixed value.

[0013] Secondly, this application also provides a process output fan-out device, the device comprising: The acquisition module is used to acquire the output events of the target process; The traversal module is used to traverse each subscriber subscribed to the target process, and for any subscriber traversed, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

[0014] Thirdly, this application provides an electronic device including a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein the processor executes the computer program to implement the process output fan-out method as described in the first aspect above.

[0015] Fourthly, this application provides a non-transitory computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, implements the process output fan-out method as described in the first aspect above.

[0016] The process output fan-out method and apparatus provided in this application, by acquiring the output events of the target process and iterating through each subscriber subscribing to the target process, enables the method and apparatus to perform corresponding output event processing for each subscriber. Furthermore, by skipping the target subscriber when it is in a canceled state, the method and apparatus avoids invalid output event delivery and allows the fan-out process of the current output event to continue processing other target subscribers who are not in a canceled state. Finally, by delivering the output event to the target private channel when the target subscriber is not in a canceled state and the buffer of the target private channel is not full, the method and apparatus utilize the buffer space of the target private channel. The method temporarily stores output events that have not yet been consumed by the target subscriber, thus allowing healthy but temporarily slow target subscribers to avoid immediately consuming every output event and tolerate a certain degree of instantaneous traffic bursts or short-term fluctuations in consumption speed. Furthermore, by setting the target subscriber to a canceled state when it is not in a canceled state and the target private channel's buffer is full, the method and device enable zombie subscribers or extremely slow subscribers to stop waiting for buffer space when they cannot consume output events in time. This reduces the impact of abnormal subscribers on the process output fan-out process, prevents a single abnormal subscriber from blocking the reception of output events from other subscribers, and improves the real-time performance and stability of the process output fan-out. Attached Figure Description

[0017] To more clearly illustrate the technical solutions in this application or the prior art, the drawings used in the description of the embodiments or the prior art will be briefly introduced below. Obviously, the drawings described below are some embodiments of the present invention. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.

[0018] Figure 1 This is a flowchart illustrating the process output fan-out method provided in this application.

[0019] Figure 2 This is a diagram illustrating the subscriber status provided in this application.

[0020] Figure 3 This is a schematic diagram of the process output fan-out device provided in this application.

[0021] Figure 4 This is a schematic diagram of the structure of the electronic device provided in this application. Detailed Implementation

[0022] To make the objectives, technical solutions, and advantages of this application clearer, the technical solutions of this application will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of this application, not all embodiments. Based on the embodiments of this application, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of this application.

[0023] Figure 1 This is a flowchart illustrating the process output fan-out method provided in this application, as shown below. Figure 1 As shown, the method may include: Step 110: Obtain the output events of the target process; Step 120: Iterate through all subscribers of the target process, and for any subscriber encountered, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the target subscriber's target private channel buffer is not full, the output event will be delivered to the target private channel. Set the target subscriber to a canceled state if the target subscriber is not in a canceled state and the target subscriber's private channel buffer is full.

[0024] It should be noted that the execution entity of the above-described process output fan-out method can be a computer device running a cloud sandbox system and capable of processing and distributing process output events, such as a server, cloud server, or other computing device. Specifically, the above-described process output fan-out method can be executed by a fan-out goroutine in the cloud sandbox system. For example, the envd daemon in the cloud sandbox system can write the output events generated by the target process to a source channel, and the fan-out goroutine can obtain the output events from the source channel and iterate through each subscriber that subscribes to the target process. This application does not impose specific limitations on this.

[0025] Specifically, a target process refers to a program execution instance that can generate output events during its execution and has the ability to provide these output events to one or more subscribers as needed. For example, a target process can be a user program running in a cloud sandbox; it can also be an application, compilation task, testing task, data processing task, or model inference task running in a container, virtual machine, or server. This application does not impose specific limitations on this.

[0026] Output events refer to data generated during the execution of the target process and capable of being transmitted to subscribers. For example, output events can be data generated by stdout (standard output) or stderr (standard error); they can also be log data, status data, debug data, or task execution results generated during the execution of the target process. This application does not impose specific limitations on this.

[0027] A subscriber is an object that subscribes to the output events of a target process and has the need to receive the output events generated by the target process. For example, a subscriber can be an IDE (Integrated Development Environment) plugin, a CLI (Command Line Interface) tool, or a monitoring system; it can also be a web console, a remote debugging client, a log collection service, a runtime status monitoring service, or other clients or services that need to obtain the target process's output events in real time. This application does not specifically limit this.

[0028] Each subscriber refers to one or more subscribers that subscribe to the same target process. For example, a client can be a subscriber to the target process. This application does not impose specific limitations on this.

[0029] The target subscriber refers to the subscriber currently being processed during the traversal of all subscribers. For example, if the subscribers include subscriber A, subscriber B, and subscriber C, then when the traversal reaches subscriber B, subscriber B can be the current target subscriber; and when the traversal continues to subscriber C, subscriber C can be the current target subscriber. This application does not impose specific limitations on this.

[0030] Traversing each subscriber of the target process refers to executing the corresponding output event handling for each subscriber of the target process. For example, subscribers can be processed sequentially according to their registration order; alternatively, subscribers can be processed according to their order of arrangement in the subscriber set. This application does not impose specific limitations on this.

[0031] A target private channel refers to a data transmission channel corresponding to a target subscriber, used to transmit output events to the target subscriber. Different target subscribers can each have their own target private channel, enabling the same output event to be delivered to different target subscribers. This application does not impose specific limitations on this.

[0032] The buffer of a target private channel refers to the storage space within the target private channel that can temporarily hold output events that have not yet been consumed by the target subscriber. For example, when the output event generation rate is temporarily higher than the target subscriber's consumption rate, the unconsumed output events can be stored in the target private channel's buffer to await subsequent consumption by the target subscriber. This application does not impose specific limitations on this.

[0033] Understandably, by setting a buffer in the target private channel, if the target subscriber fails to consume the output event in a short period of time, the output event can still be delivered to the target private channel as long as the buffer is not full, without waiting for the target subscriber to complete consumption immediately. Therefore, the buffer of the target private channel can absorb instantaneous traffic bursts and provide a certain buffer space for target subscribers who experience temporary slowdowns.

[0034] The cancellation state indicates that the target subscriber is no longer participating in the normal delivery process of output events. For example, the target subscriber may enter the cancellation state if the client connection is abnormal; it may also enter the cancellation state if the target subscriber is unable to consume output events in a timely manner for an extended period; or it may enter the cancellation state if the target subscriber actively unsubscribes or no longer needs to receive output events. This application does not impose specific limitations on this.

[0035] Skipping a target subscriber means that for the current output event, the output event delivery to the target private channel corresponding to the target subscriber is no longer executed, and processing continues for other subscribers. For example, when iterating through subscribers, if the current target subscriber is already in a canceled state, the output event delivery judgment for the current target subscriber can be stopped, and the process can continue to the next subscriber. This application does not impose specific limitations on this.

[0036] Specifically, in step 110, the user can run the target process in the cloud sandbox system. During the execution of the target process, it can continuously generate standard output and / or standard error. The cloud sandbox system can acquire the standard output and / or standard error generated by the target process and generate corresponding output events based on the standard output and / or standard error. For example, a fan-out goroutine can acquire the output events generated by the target process and perform distribution processing for each subscriber based on the acquired output events.

[0037] In step 120, after obtaining the output event, it is possible to traverse each subscriber of the current target process and take the subscriber currently being processed during the traversal as the target subscriber.

[0038] For each target subscriber encountered during the iteration, it can be determined whether the target subscriber is currently in a canceled state.

[0039] Optionally, if the target subscriber is in a canceled state, it can be indicated that there is no need to continue delivering output events to the target subscriber. Therefore, the current target subscriber can be skipped, and the delivery of the current output event to the target private channel corresponding to the current target subscriber can no longer be performed, and other subscribers can continue to be traversed.

[0040] Optionally, if the target subscriber is not in a canceled state and the target subscriber's target private channel buffer is not full, it indicates that the target subscriber is still participating in the normal reception of output events and the target subscriber's target private channel is still able to continue receiving new output events. Therefore, the current output event can be delivered to the target private channel.

[0041] Understandably, even if the target subscriber has actually encountered an error, as long as the target subscriber is not in a canceled state and the buffer of the target private channel is not full, the current output event can still be delivered to the target private channel.

[0042] Optionally, if the target subscriber is not in a canceled state, but the target subscriber's private channel buffer is full, it indicates that unconsumed output events are continuously accumulating in the target private channel, causing the buffer to reach a full state. In this case, if we continue to wait for the target subscriber to consume the output events in the target private channel and release the buffer space, the fan-out processing for the current output event may be affected by the current target subscriber. Therefore, we can set the current target subscriber to a canceled state and continue processing the current output event for other subscribers.

[0043] For example, the subscribers currently subscribing to the target process include subscriber A, subscriber B, and subscriber C. Among them, subscriber A is a healthy subscriber, subscriber B is a zombie subscriber, and subscriber C is an extremely slow subscriber.

[0044] In this context, a zombie subscriber refers to a subscriber whose subscription relationship with the target process still exists, but which is no longer able to normally consume the target process's output events. For example, during the recovery process after pausing and creating a memory snapshot in a cloud sandbox, client network connections established before the pause may have been lost, but the corresponding subscription relationship was not cleared in time, preventing the target subscriber from continuing to normally consume the target process's output events. Such a target subscriber can be called a zombie subscriber. As another example, due to network anomalies, abnormal client exits, or the client's network connection status not being detected in time, a target subscriber may no longer be able to normally consume the target process's output events, but the corresponding subscription relationship still exists; in such cases, the target subscriber can also be considered a zombie subscriber. This application does not impose specific limitations on this.

[0045] An extremely slow subscriber refers to a subscriber that can still consume output events from the target process, but the rate of consumption remains consistently slow, causing unconsumed output events to accumulate on the target's private channel. For example, an extremely slow subscriber could be a target subscriber whose slow output event consumption is due to a decrease in network transmission speed; it could also be a target subscriber whose slow output event consumption is due to insufficient computing resources, heavy processing load, or a decrease in client processing power. This application does not specifically limit this.

[0046] A healthy subscriber refers to a subscriber who is able to continuously consume output events according to the normal processing procedure. This application does not specifically limit this definition.

[0047] For subscriber A, since subscriber A can continuously consume the output events of the target process, subscriber A's target private channel can continuously maintain a buffer that is not full. Therefore, as long as subscriber A is not in a canceled state, the output events generated by the target process can be continuously delivered to subscriber A's target private channel.

[0048] For subscriber B, as long as subscriber B has just become a zombie subscriber and the buffer of the target private channel corresponding to subscriber B is not yet full, output events generated by the target process can continue to be delivered to the target private channel corresponding to subscriber B. As subscriber B continues to be unable to consume output events, the buffer of the target private channel gradually becomes full. When the buffer of the target private channel reaches a full state, subscriber B can be set to a canceled state. When subsequent output events are traversed to subscriber B again, subscriber B can be skipped directly.

[0049] For subscriber C, if subscriber C's consumption rate is slow but the target private channel corresponding to subscriber C still has remaining buffer space, output events can continue to be delivered to the target private channel corresponding to subscriber C. If subscriber C can consume some output events in time and release buffer space, normal delivery can continue; if subscriber C's consumption rate continues to be lower than the rate at which the target process generates output events, and eventually the buffer of the target private channel reaches a full state, subscriber C can be set to a canceled state. When subsequent output events are traversed to subscriber C again, subscriber C can be skipped directly.

[0050] Compared to existing unbuffered private channel schemes, the fan-out blocking time of existing schemes can be as long as approximately 924 seconds (about 15 minutes) after the emergence of zombie subscribers, corresponding to the default tcp_retries2 parameter on Linux systems. This application, however, can complete the eviction as soon as the next output event arrives after the target private channel buffer is full. The eviction trigger latency is approximately the buffer capacity divided by the output event rate. For example, with a buffer capacity of 64 output events and an output event rate of 1000 output events per second, the eviction trigger latency is approximately 64 milliseconds, which is about four orders of magnitude lower than existing schemes, thus significantly improving the real-time performance of process output fan-out.

[0051] The process output fan-out method provided in this application obtains the output events of the target process and iterates through each subscriber to the target process, enabling the method to perform corresponding output event processing for each subscriber. Furthermore, by skipping the target subscriber when it is in a canceled state, the method avoids invalid output event delivery and allows the fan-out process of the current output event to continue processing other target subscribers who are not in a canceled state. Finally, by delivering the output event to the target private channel when the target subscriber is not in a canceled state and the target private channel's buffer is not full, the method utilizes the target private channel's buffer space to temporarily store unreleased events. Output events not consumed by the target subscriber are processed so that healthy but temporarily slow target subscribers do not need to immediately complete the consumption of every output event, tolerating a certain degree of instantaneous traffic bursts or short-term fluctuations in consumption speed. Furthermore, by setting the target subscriber to a canceled state when it is not in a canceled state and the target private channel's buffer is full, this method enables zombie subscribers or extremely slow subscribers to stop waiting for buffer space when they cannot consume output events in time. This reduces the impact of abnormal subscribers on the process output fan-out process, avoids a single abnormal subscriber blocking the reception of output events from other subscribers, and improves the real-time performance and stability of the process output fan-out.

[0052] In one embodiment, setting a target subscriber to a canceled state includes: Close the cancellation instruction channel associated with the target subscriber; the closed status of the cancellation instruction channel indicates that the target subscriber is in a canceled state. Close the target private channel of the target subscriber, and exit the event reading loop for the target private channel when the consuming coroutine detects that the target private channel is closed.

[0053] Specifically, a cancellation indication channel refers to a data channel associated with a target subscriber and used to indicate whether the target subscriber is in a cancelled state. For example, a cancellation indication channel could be a "done" channel corresponding to the target subscriber; it could also be a signal channel or status channel specifically used to transmit cancellation status. This application does not impose any specific limitations on this.

[0054] The cancellation indication channel is used to indicate whether the target subscriber is in a canceled state. For example, when the cancellation indication channel is closed, it can be determined that the target subscriber is in a canceled state; when the cancellation indication channel is not closed, it can be determined that the target subscriber is not in a canceled state. This application does not impose specific limitations on this.

[0055] A consumer coroutine refers to a concurrent execution unit that corresponds to a target subscriber and is used to continuously read output events from the target's private channel. For example, a consumer coroutine can be a consumer goroutine in the Go runtime environment; it can also be an asynchronous consumption task, worker coroutine, or event consumption task in other concurrent runtime environments. This application does not specifically limit it in this regard.

[0056] An event reading loop refers to the process by which a consuming coroutine continuously reads output events from a target private channel according to a preset loop logic. For example, an event reading loop can use a for range loop to continuously read output events from the target private channel; it can also use other loop structures that can repeatedly execute channel readings and detect channel status. This application does not impose specific limitations on this.

[0057] Closing the target private channel refers to putting the target private channel corresponding to the target subscriber into a closed state, so that the consuming coroutine can detect that the target private channel has been closed. For example, the target private channel can be closed when the target subscriber is set to an unfollowed state; it can also be closed when it is determined that it is no longer necessary to provide output events to the target subscriber through the target private channel. This application does not make specific limitations in this regard.

[0058] Specifically, when the target subscriber is not in a canceled state, and the target subscriber's target private channel buffer is full, the target subscriber can be set to a canceled state.

[0059] When setting a target subscriber to a canceled state, the cancel indication channel associated with the target subscriber can be closed first. The cancel indication channel indicates whether the target subscriber is in a canceled state. When the cancel indication channel is closed, it indicates that the target subscriber is in a canceled state. For example, the cancel indication channel could be the "done" channel associated with the target subscriber. When it is determined that the target subscriber needs to be set to a canceled state, the corresponding "done" channel can be closed, and the subsequent fan-out loop can skip this subscriber by checking with `isCancelled()`. When other output events generated by the target process are iterated to the target subscriber again, the fact that the target subscriber's cancel indication channel has been closed indicates that the target subscriber is in a canceled state, and the target subscriber can be skipped.

[0060] The consuming coroutine continuously reads output events from the target private channel and consumes and processes the read output events.

[0061] If the target subscriber receives the output events normally, the consumption coroutine can continue to execute the event reading loop for the target private channel and continue to perform subsequent consumption processing.

[0062] When the target subscriber is set to an unfollowed state, subsequent output events generated by the target process can be skipped during the fan-out process, and no new output events will be delivered to the target subscriber's private channel. In this case, if the target private channel remains in its original state, the consuming coroutine may continue to execute the event reading loop for the target private channel, waiting for new output events to appear in the target private channel. However, during subsequent fan-out processes, no new output events will be delivered to the target private channel, potentially causing the consuming coroutine to remain in the event reading loop for an extended period.

[0063] Therefore, the target private channel of the target subscriber can be closed. When the target private channel is closed, the consuming goroutine can detect that the target private channel is closed when performing event reading for the target private channel, and exit the event reading loop for the target private channel based on the closed status of the target private channel. For example, the data sending operation corresponding to a zombie subscriber may last for about 15 minutes due to waiting for TCP (Transmission Control Protocol) retransmission timeout. At this time, if the private channel is not closed, the corresponding event consumption processing may be blocked for a long time, which poses a risk of goroutine leakage. By causing the consuming goroutine currently performing a for range ch operation to exit normally when it receives ok=false, the goroutine leakage is eliminated.

[0064] Optionally, in one implementation, the fan-out coroutine can use a select statement with a default branch to perform non-blocking output event delivery to the target subscriber. If the target private channel can receive output events, the output event is delivered to the target private channel; if the cancellation indicator channel is closed, the target subscriber is skipped; if the target private channel's buffer is full and the current output event cannot be written immediately, the default branch is triggered, and the target subscriber is actively evicted. For example, cancel() can be called to close the done channel, and closeCh() can be called to close the target private channel, putting the target subscriber into a canceled state and notifying the consuming coroutine to exit the event reading loop.

[0065] The process output fan-out method provided in this application closes the cancellation indicator channel associated with the target subscriber and uses the closed state of the cancellation indicator channel to represent that the target subscriber is in a cancelled state. This allows the method to clearly identify that the target subscriber has been cancelled using the state of the cancellation indicator channel, so that the target process can recognize the cancellation state of the target subscriber when generating output events in the future, and avoids continuing to perform invalid output event delivery for target subscribers who can no longer participate in output events normally. Furthermore, by closing the target private channel corresponding to the target subscriber and exiting the event reading loop for the target private channel when the consuming coroutine detects that the target private channel is closed, this method reduces the risk of leakage and improves the operational stability of the process output fan-out process.

[0066] In one embodiment, iterating through the subscribers subscribing to the target process includes: Add a read lock to the subscriber list used to record each subscriber, and obtain a snapshot of the subscribers corresponding to the subscriber list; Release the read lock; Iterate through each subscriber based on the subscriber snapshot.

[0067] Specifically, the subscriber list is used to record each subscriber of the currently subscribed target process. For example, the subscriber list can record each subscriber in the order of their registration; it can also record each subscriber according to their identification information, reference information, or other information that can locate each subscriber. This application does not impose specific limitations on this.

[0068] A read lock is a lock used to restrict concurrent operations that may affect the consistency of shared data reads during the reading of shared data. For example, a read lock can be implemented using a read-write mutex; it can also be implemented using other locking mechanisms that can control concurrent access to the subscriber list during reading. This application does not specifically limit this.

[0069] A subscriber snapshot can be a set of subscribers obtained by copying each subscriber recorded in the current subscriber list; or it can be a set of subscribers formed based on the reference information corresponding to each subscriber in the current subscriber list. This application does not impose specific limitations on this.

[0070] Snapshot-based traversal refers to traversing each subscriber based on a subscriber snapshot. For example, a read lock can be acquired for the subscriber list within a short time, and a subscriber snapshot can be generated. After the subscriber snapshot is generated, the read lock is released, and then subsequent processing is performed on each subscriber in the subscriber snapshot. This application does not impose specific limitations on this.

[0071] It is understandable that the subscriber list is shared data that may be accessed by multiple concurrent processing processes. If the lock corresponding to the subscriber list is held throughout the entire output event fan-out process, and output event delivery is performed for each subscriber while the lock is held, the processing time for the target subscriber may extend the holding time of the lock corresponding to the subscriber list, thus causing other processing processes that need to access the subscriber list to be in a continuous waiting state.

[0072] Specifically, after obtaining the current output events of the target process, when it is necessary to iterate through all the subscribers currently subscribed to the target process, a read lock can be added to the subscriber list used to record each subscriber. For example, goroutines can use sync.RWMutex internally to implement concurrent access control for the subscriber list.

[0073] After adding a read lock, you can read each subscriber currently recorded in the subscriber list and generate a snapshot of the subscribers corresponding to the subscriber list based on the read subscribers.

[0074] Understandably, the subscriber snapshot is used to determine which subscribers need to be traversed during the fan-out process of this output event. After the subscriber snapshot is formed, the traversal processing corresponding to the current output event can continue to be executed based on the subscriber snapshot, without having to continuously access the subscriber list throughout the entire process of executing the output event for each subscriber.

[0075] After obtaining the subscriber snapshots corresponding to the subscriber list, the fanout coroutine can release the read locks corresponding to the subscriber list, so that the subscriber list is no longer continuously occupied by the current fanout process.

[0076] Subsequently, after releasing the read lock, each subscriber can be traversed based on the subscriber snapshot. In other words, the access phase to the subscriber list can be separated from the output event handling phase for each subscriber. Specifically, during the subscriber list access phase, a read lock is acquired on the subscriber list, and a subscriber snapshot is obtained based on the current subscriber list; after the subscriber snapshot is obtained, the read lock is released; during the output event handling phase for each subscriber, each subscriber is traversed based on the already obtained subscriber snapshot, without needing to continue holding the read lock corresponding to the subscriber list.

[0077] The process output fan-out method provided in this application reduces the impact of concurrent access to the subscriber list on the traversal process by adding a read lock to the subscriber list used to record each subscriber and obtaining the corresponding subscriber snapshot under the protection of the read lock. Furthermore, by releasing the read lock after obtaining the subscriber snapshot and traversing each subscriber according to the subscriber snapshot, this method separates the subscriber list reading stage from the output event stage for each subscriber, reduces lock contention in concurrent scenarios, improves the concurrent processing efficiency of the process output fan-out process, and thus enhances the real-time performance and stability of the process output fan-out.

[0078] In one embodiment, the method further includes at least one of the following: In the case of unregistering the target subscriber, set the target subscriber to the canceled state; add a write lock to the subscriber list used to record each subscriber, and remove the target subscriber from the subscriber list after adding the write lock; When registering a new subscriber, obtain the source channel corresponding to the target process and perform an initial check on the closed status of the source channel. If the initial check determines that the source channel is not closed, add a write lock to the subscriber list used to record each subscriber, and after adding the write lock, perform a second check on the closed status of the source channel. If the second check determines that the source channel is not closed, add the new subscriber to the subscriber list. If the initial or second check determines that the source channel is closed, return the pre-closed private channel to the caller corresponding to the new subscriber.

[0079] Specifically, unregistering a target subscriber refers to terminating the subscription relationship between the target subscriber and the target process, and preventing the target subscriber from being traversed by subsequent output events. For example, the target subscriber can be unregistered when it actively ends its subscription; it can also be unregistered when the client corresponding to the target subscriber logs out, experiences a connection error, or no longer needs to receive output events from the target process. This application does not impose specific limitations on this.

[0080] A write lock is a lock used to restrict other concurrent operations from modifying the subscriber list during operations such as adding, deleting, or otherwise altering its contents. For example, a write lock can be implemented using a write lock corresponding to a read-write mutex; it can also be implemented using other locking mechanisms that can mutually exclude modifications to the subscriber list. This application does not specifically limit its implementation.

[0081] Registering a new subscriber refers to establishing a subscription relationship between a new subscriber and a target process, enabling the new subscriber to receive output events generated by the target process. For example, a new subscriber can be registered in response to a subscription request initiated by a client; it can also be registered in response to subscription requests initiated by monitoring services, logging services, or debugging services. This application does not impose specific limitations on this.

[0082] A source channel refers to a data channel used to carry output events generated by the target process and provide output events to the fan-out process. For example, output events generated by the target process can be written to a source channel, and then the fan-out coroutine can retrieve the output events from the source channel. This application does not impose specific limitations on this.

[0083] The closed state of the source channel indicates whether the source channel can continue to provide output events generated by the target process. For example, when the source channel is not closed, it indicates that it is still possible to obtain output events of the target process through the source channel; when the source channel is closed, it indicates that it is no longer possible to provide output events of the target process through the source channel. This application does not impose specific limitations on this.

[0084] The first check refers to the check performed before adding a write lock to the subscriber list to determine whether the source channel is currently closed. This application does not specifically limit this.

[0085] The second check refers to the check performed again after adding a write lock to the subscriber list to determine whether the source channel is currently closed. This application does not specify this in detail.

[0086] A pre-closed private channel refers to a private channel that is already closed before returning to the caller corresponding to the new subscriber. For example, when it is determined that the source channel corresponding to the target process is closed, a closed private channel can be created or obtained, and this private channel can be directly returned to the caller corresponding to the new subscriber. Here, the caller refers to the processing object that initiates the new subscriber registration operation and receives the registration result; the caller can be the program logic that calls the Fork() operation to register the new subscriber. This application does not specifically limit this.

[0087] Optionally, in the case of canceling a target subscriber, the target subscriber can be set to a canceled state first.

[0088] Setting a target subscriber to an unfollowed state allows you to skip it during iterations of subsequent output events generated by the target process, preventing it from participating in normal event delivery. For example, when performing a target subscriber's remove operation, you can call `cancel()` to set it to an unfollowed state. By calling `cancel()` first, you remove the target subscriber's potential influence on the fan-out process, preventing subsequent fan-out loops from delivering output events to the target subscriber as normal.

[0089] After successfully acquiring a write lock, the target subscriber can be removed from the subscriber list. For example, the subscriber list can be stored as a slice containing the current subscribers. After acquiring a write lock, the element corresponding to the target subscriber can be deleted from that slice, so that the target subscriber is no longer included in the current subscriber list.

[0090] Optionally, when registering a new subscriber, the source channel corresponding to the target process can be obtained, and the registration of the new subscriber can be determined based on the current closed state of the source channel.

[0091] Subsequently, the closed state of the source channel can be checked for the first time. For example, Fork() is used to register a new subscriber. When Fork() is executed, the closed state of the source channel can be checked first through a fast path atomic check. Here, fast path can be understood as a fast detection path performed before entering the processing path that requires acquiring a write lock.

[0092] If the initial detection confirms that the source channel is closed, it indicates that the source channel corresponding to the target process is no longer providing new output events, and therefore there is no need to add new subscribers to the subscriber list. In this case, the pre-closed private channel can be directly returned to the caller corresponding to the new subscriber. For example, when Fork() determines that the source channel is closed during the fastpath atomic check phase, it can directly return the pre-closed private channel to the caller corresponding to the new subscriber that called Fork(). Since the returned private channel was already closed before being returned, the caller can immediately end the for range loop when executing it on that private channel, without having to wait for the target process to generate new output events.

[0093] If the initial detection confirms that the source channel is not closed, a write lock can be added to the subscriber list used to record each subscriber.

[0094] It is understandable that there may be a time interval between the completion of the first detection and the successful addition of the write lock. During this time interval, the closed state of the source channel may change. For example, after the first detection determines that the source channel is not closed but before the write lock is successfully added, the output event processing of the target process may end, causing the source channel to change from an open state to a closed state. Adding a new subscriber directly to the subscriber list based solely on the result of the first detection may result that no longer reflects the true state of the current source channel.

[0095] After successfully adding a write lock to the subscriber list, a second check can be performed on the closed status of the source channel. For example, after Fork() successfully acquires the write lock, a re-check can be performed on the closed status of the source channel within the write lock-protected processing interval, that is, to check again whether the source channel is currently closed.

[0096] If the second detection confirms that the source channel is not closed, it indicates that the source channel can still provide output events to the target process during the current write-lock protection phase. In this case, the new subscriber can be added to the subscriber list.

[0097] If the second check determines that the source channel is closed, even if it wasn't closed during the first check, the new subscriber can be removed from the subscriber list. Instead, the pre-closed private channel can be returned to the caller corresponding to the new subscriber. For example, the first fast path atomic check might determine that the source channel is not closed, thus entering the write lock acquisition process. However, upon successfully acquiring the write lock and performing a re-check, it might be determined that the source channel is closed. In this case, new subscriber registration can be stopped, and the pre-closed private channel can be returned to the caller corresponding to the new subscriber. After the caller obtains the pre-closed private channel, if a for range loop is executed on that private channel, the loop can terminate immediately because the private channel is already closed. This avoids the caller continuing to wait for output events from the private channel even when the target process can no longer provide output events.

[0098] Understandably, the first and second checks form a dual detection mechanism. The first check can quickly rule out the possibility that the source channel is already closed before acquiring the write lock, thus preventing the subsequent write lock acquisition and new subscriber registration process from proceeding even when the source channel is closed. The second check can reconfirm the current state of the source channel if the write lock has already been acquired, preventing the incorrect addition of new subscribers to the subscriber list if the source channel's state changes between the end of the first check and the acquisition of the write lock.

[0099] The process output fan-out method provided in this application achieves mutual exclusion control over the subscriber list modification process by first setting the target subscriber to an unregistered state, then adding a write lock to the subscriber list, and finally removing the target subscriber from the subscriber list when the target subscriber is unregistered. This reduces the possibility of multiple concurrent modification operations interfering with each other. Furthermore, by performing a first check on the closed state of the source channel when registering a new subscriber, and adding a write lock after confirming that the source channel is not closed, followed by a second check on the closed state of the source channel after adding the write lock, this method reduces the possibility of incorrectly adding new subscribers to the subscriber list due to concurrent state changes, thereby improving the real-time performance and stability of process output fan-out.

[0100] In one embodiment, the method further includes: Maintain the subscriber status of each subscriber; the subscriber status includes the active status, canceled status, and channel closed status, which are sequentially converted one-way; If a target subscriber is unsubscribed, the target subscriber's subscriber status will be updated from active to unsubscribed. If the target private channel is closed, the subscriber status of the target subscriber will be updated from canceled to closed. Stop delivering output events to the target private channel if the target subscriber's channel is closed.

[0101] Specifically, subscriber status is used to characterize the current processing stage of a subscriber. For example, subscriber status can be recorded through a status field; it can also be recorded through enumeration values, status identifiers, or other information that can distinguish different processing stages. This application does not impose specific limitations on this.

[0102] An active state indicates that the target subscriber is still able to participate in the normal fan-out processing of the target process's output events.

[0103] The cancel status indicates that the target subscriber has been canceled and there is no need to deliver output events to the target subscriber in the future.

[0104] The "channel closed" status indicates that the target private channel corresponding to the target subscriber has been closed, and the target private channel is no longer used to receive subsequent output events.

[0105] Sequential one-way transition refers to the subscriber's state transitioning sequentially according to a preset state order, without reverting from a later state to a previous one. For example, the subscriber's state can transition sequentially in the order of "active state → canceled state → channel closed state". This application does not impose specific limitations on this.

[0106] Specifically, if the target subscriber is normally participating in receiving the output events of the target process and has not yet been canceled, the subscriber state of the target subscriber can be maintained as active.

[0107] When a target subscriber meets the cancellation conditions and needs to be cancelled, the subscriber's status can be updated from active to cancelled. For example, if a target subscriber is not in a cancelled state, but the buffer of its target private channel is full, the target subscriber can be set to cancelled. Correspondingly, the subscriber's status can be synchronously updated from active to cancelled.

[0108] If the target subscriber is already in a canceled state, closing the target subscriber's private channel will update the target subscriber's subscriber status from canceled to closed.

[0109] If the target subscriber's channel is closed, you can stop delivering output events to the target private channel.

[0110] For example, when the fan-out loop iterates to the current target subscriber, the current subscriber state can be determined. If the subscriber state is active, the normal output event handling logic can be followed to determine whether to send an output event to the target private channel; if the subscriber state has entered the canceled state, the target subscriber can be processed according to the cancellation state handling logic; if the subscriber state has entered the channel-closed state, no new output events will be written to the target private channel.

[0111] Understandably, if the fan-out loop continues to attempt to write new output events to the target private channel once it is closed, it may trigger an exception indicating that data is being written to a closed channel. For example, by stopping the delivery of output events to the target private channel when the target subscriber is in the ChannelClosed state, the fan-out loop can be prevented from continuing to write output events to a closed channel. Furthermore, even after the target private channel is closed, the consumer coroutine corresponding to the target subscriber can still detect its closure via channel close, without relying on external polling.

[0112] For example, initially, the target subscriber can normally consume the output events generated by the target process, and its subscriber state can be maintained as Active. As the target process continues to generate output events, if the target subscriber is unable to consume the output events in the target private channel in a timely manner, causing the target private channel's buffer to reach a full state, the target subscriber can be canceled, and its subscriber state can be updated from Active to Cancelled. If the target subscriber is already in Cancelled, the target private channel can be further closed. After the target private channel is closed, the target subscriber's subscriber state is updated from Cancelled to ChannelClosed. Thus, by maintaining a subscriber state machine of "Active → Cancelled → ChannelClosed" and ensuring that the state transitions are unidirectional and monotonically progressive, it can be guaranteed that the fan-out loop will not write to a closed channel (writing to a closed channel will cause a panic), and it also allows the consumergoroutine to perform corresponding processing through channel close.

[0113] Figure 2 This is a diagram illustrating the subscriber status provided in this application, such as... Figure 2 As shown, the subscriber state corresponding to the target subscriber can be maintained. The subscriber state includes an active state, a canceled state, and a channel-closed state that transition sequentially in a one-way direction. Here, Active represents the active state, Cancelled represents the canceled state, and ChannelClosed represents the channel-closed state. Active can serve as the "initial state" of the target subscriber, indicating that the target subscriber can participate in the normal delivery of output events.

[0114] When a "cancellation operation" is triggered for a target subscriber in the Active state, the subscriber's state can be updated from Active to Cancelled. While the target subscriber is in Cancelled, delivery can be "skipped," meaning no further output events will be delivered to the target subscriber's private channel. Furthermore, when the target private channel is closed, the subscriber's state can be updated from Cancelled to ChannelClosed. While the target subscriber is in ChannelClosed, delivery can be "stopped, and the consuming coroutine exits," meaning delivery of output events to the closed target private channel will cease, and the consuming coroutine will exit its event reading loop upon detecting the closure of the target private channel.

[0115] Therefore, the subscriber state of the target subscriber can be unidirectionally transformed in the order of "Active→Cancelled→ChannelClosed". The transformation between the three states is irreversible, thus ensuring that the target private channel will not be written to again after it is closed, thereby improving the operational stability of the process output fan-out process.

[0116] The process output fan-out method provided in this application maintains the subscriber state of each subscriber and sequentially transitions the subscriber state to active, canceled, and closed states. This ensures that the method updates the subscriber state in an orderly manner according to the current actual processing stage of the target subscriber, preventing reverse changes in subscriber state from causing target subscribers who have already canceled or whose target private channel has been closed to be processed as normal active target subscribers again. Furthermore, by updating the target subscriber's subscriber state from active to canceled when canceling the target subscriber and from canceled to closed when closing the target private channel, and by stopping the delivery of output events to the target private channel when the target subscriber is in the closed state, this method enables the output event fan-out process to perform corresponding processing according to the current subscriber state of the target subscriber, thereby improving the operational stability of the process output fan-out process.

[0117] In one embodiment, the method further includes: Configure the single-execution control component corresponding to the target subscriber; The single-execution control component controls the number of times the target operation to close the cancellation instruction channel and close the target private channel can be performed.

[0118] Specifically, the single-execution control component is used to limit the number of times the target operation is executed. For example, the single-execution control component can be `sync.Once` in the Go runtime environment; it can also be other control components with single-trigger, count limiting, or idempotent control capabilities. This application does not impose specific limitations on this.

[0119] The target number of operations refers to the number of times the closing cancellation instruction channel and closing the target private channel are allowed to be executed. For example, when using a single-execution control component, the target number of operations can be one, ensuring that the operations of closing the cancellation instruction channel and closing the target private channel are each actually executed only once. This application does not impose a specific limitation on this.

[0120] Understandably, in concurrent scenarios, cancellation processing for the same target subscriber may be triggered by multiple processes. If multiple processes directly execute to close the cancellation instruction channel or close the target private channel, the same channel may be closed repeatedly. In some program runtime environments, repeatedly closing an already closed channel may trigger a panic, thus affecting the normal operation of the process's output fan-out process. Therefore, a single-execution control component can be configured for the target subscriber to limit the actual number of times the cancellation instruction channel and the target private channel are closed.

[0121] Specifically, when a target subscriber needs to be set to a canceled state, the cancellation instruction channel associated with the target subscriber and the target subscriber's private channel can be closed.

[0122] For operations involving closing cancellation indicator channels, the target number of operations can be controlled using a single-execution control component. For example, `sync.Once` can be used to control the single-execution of closing cancellation indicator channels. When cancellation is triggered for the first time for the same target subscriber, the `done` channel associated with that subscriber can be closed, indicating that the subscriber is in a cancelled state. If subsequent cancellations for the same target subscriber are triggered again due to other concurrent processing, the single-execution control component can limit the re-execution of closing the `done` channel, thus preventing a secondary closure of an already closed `done` channel.

[0123] Furthermore, the number of times the target private channel can be closed can be controlled through a single-execution control component. For example, `sync.Once` can be used to control the single-execution of the target private channel closure operation corresponding to `closeCh()`. When the target private channel closure process is executed for the first time for the target subscriber, `closeCh()` can be called to close the target subscriber's target private channel. If subsequent concurrent processing triggers the closure of the target private channel again, the single-execution control component can be used to limit the re-execution of the closure operation corresponding to `closeCh()`, thereby avoiding the secondary closure of the already closed target private channel.

[0124] In other words, in one implementation, both the closing operation corresponding to the cancellation instruction channel and the closing operation corresponding to the target private channel can be constrained by the single execution control component, so that the two closing operations are actually executed only once.

[0125] By using sync.Once, the idempotency of the closing / cancellation instruction channel and the corresponding operation of the closing target private channel is guaranteed, so that even if the closing operation is requested multiple times in a concurrent scenario, it will only be executed according to the target number of operations.

[0126] The process output fan-out method provided in this application configures a single-execution control component corresponding to the target subscriber, and then controls the target number of operations to close the cancellation instruction channel and the target private channel through the single-execution control component. This method avoids the cancellation instruction channel or the target private channel that has already been closed being closed again, thereby reducing the risk caused by secondary closure in concurrent scenarios and improving the concurrency security and operational stability of the process output fan-out process.

[0127] In one embodiment, the buffer capacity of the target private channel is a fixed value.

[0128] Specifically, buffer capacity refers to the number of output events that the target private channel's buffer can hold. For example, buffer capacity can represent the maximum number of output events that the target private channel can temporarily store before the target subscriber has consumed the corresponding output event. This application does not impose a specific limitation on this.

[0129] A fixed value refers to a value pre-configured for the target private channel to limit its buffer capacity. For example, the fixed value can be 64, meaning the target private channel's buffer can temporarily store a maximum of 64 output events that have not yet been consumed by the target subscriber; it can also be 256, meaning the target private channel's buffer can temporarily store a maximum of 256 output events that have not yet been consumed by the target subscriber; or it can be other fixed values ​​pre-configured based on the target process's output event generation rate, the target subscriber's output event consumption capacity, or system resource availability. This application does not specifically limit this value.

[0130] Specifically, when configuring the target private channel for the target subscriber, a fixed buffer capacity can be pre-set for the target private channel. For example, the buffer size `subscriberBufSize` of the target private channel can be configured to 64 events. In this case, the buffer of the target private channel can temporarily hold a maximum of 64 output events that have not yet been consumed by the target subscriber. As another example, the buffer size `subscriberBufSize` of the target private channel can be configured to 256 events. In this case, the buffer of the target private channel can temporarily hold a maximum of 256 output events that have not yet been consumed by the target subscriber.

[0131] The process output fan-out method provided in this application sets the buffer capacity of the target private channel to a fixed value, thereby reserving a certain amount of temporary storage space for the target subscriber. When the target subscriber fails to consume the output event in a short period of time, the buffer of the target private channel can be used to temporarily store the output event to be consumed. This method can absorb short-term bursts of output event traffic, tolerate short-term consumption fluctuations of healthy target subscribers, and limit the buffer resource occupation of a single target subscriber. It reduces the impact of short-term consumption speed fluctuations of target subscribers on the output event fan-out process, thereby reducing the impact of abnormal subscribers on the process output fan-out process, preventing a single abnormal subscriber from blocking the output event reception of other subscribers, and improving the real-time performance and stability of process output fan-out.

[0132] To facilitate a clearer understanding of the technical solutions of the various embodiments of this application, further explanation is provided.

[0133] Optionally, in one embodiment, the subscribers currently subscribing to the target process include subscriber A and subscriber B. Subscriber A is a healthy subscriber capable of normally consuming the output events of the target process, while subscriber B is a zombie subscriber. The consumption coroutine corresponding to subscriber B is blocked on the output event sending operation corresponding to stream.Send(), and cannot complete the output event sending for approximately 60 seconds. Therefore, subscriber B cannot continue to normally consume the output events in the target private channel.

[0134] The target process continuously generates output events and writes these events to its corresponding source channel via a streaming gRPC interface. The source channel continuously provides output events at a rate of 1000 events per second. After the fan-out coroutine obtains the output events from the source channel, it iterates through subscribers A and B and executes the corresponding processing for each output event.

[0135] Subscriber A and Subscriber B each correspond to a target private channel. The buffer capacity of the target private channel can be set to 64 output events.

[0136] At t=0, neither subscriber A nor subscriber B is in a canceled state, and the buffers of the target private channels corresponding to subscribers A and B are not full. Therefore, the fan-out coroutine can deliver output events to the target private channels corresponding to subscribers A and B, respectively.

[0137] For subscriber A, because subscriber A can continuously consume output events from the target private channel, the target private channel corresponding to subscriber A can continuously release buffer space. Therefore, the target private channel corresponding to subscriber A can continuously maintain a buffer that is not full, and the fan-out coroutine can continue to send subsequent output events generated by the target process to the target private channel corresponding to subscriber A. For subscriber B, because the consuming coroutine corresponding to subscriber B is blocked in stream.Send(), subscriber B cannot continue to consume output events from the target private channel normally. As the target process continues to generate output events, output events that have not yet been consumed by subscriber B continue to accumulate in the target private channel corresponding to subscriber B.

[0138] At t=64ms, based on the source channel's output rate of 1000 output events per second, approximately 64 unconsumed output events can accumulate in the target private channel corresponding to subscriber B. Since the buffer capacity of the target private channel corresponding to subscriber B is 64 output events, the buffer of the target private channel corresponding to subscriber B is full at this time.

[0139] At t=65ms, the 65th output event arrives. When the fan-out coroutine iterates to subscriber B and attempts to process the output event for subscriber B, it can be determined that subscriber B is not yet canceled, but the buffer of the target private channel corresponding to subscriber B is already full. At this point, a select statement with a default branch can be used to deliver the output event. When the buffer of the target private channel of subscriber B is full and the current output event cannot continue to be written normally, the default branch can be triggered, and cancel() and closeCh() can be called to perform eviction processing on subscriber B.

[0140] Calling `cancel()` closes the cancellation indicator channel associated with subscriber B, for example, closing the `done` channel corresponding to subscriber B. Once the cancellation indicator channel is closed, it indicates that subscriber B is in a cancelled state. When the fan-out coroutine iterates to subscriber B again, it can use `isCancelled()` to check the cancelled state of subscriber B and skip subscriber B, ceasing to send new output events to the target private channel corresponding to subscriber B.

[0141] Calling `closeCh()` closes the target private channel corresponding to subscriber B. The consumer coroutine corresponding to subscriber B was originally continuously executing a `for range ch` event reading loop for the target private channel. When the target private channel is closed, the consumer coroutine can obtain `ok=false` when reading from the target private channel and exit the event reading loop accordingly, thus preventing the consumer coroutine corresponding to subscriber B from remaining in the event reading loop for an extended period.

[0142] Therefore, at t=65ms, subscriber B can complete the cancellation and target private channel closure process and be isolated from the subsequent normal output event fan-out process.

[0143] Starting from t=65ms, the target process continues to generate output events. For subscriber A, since subscriber A can still consume output events normally, the fan-out coroutine can continue to deliver subsequent output events to the target private channel corresponding to subscriber A. Subscriber A continues to receive output events generated by the target process normally, and the reception delay corresponding to the output events is not affected by the continued abnormal state of subscriber B.

[0144] For subscriber B, since subscriber B is already in a canceled state, when the fan-out process corresponding to the subsequent output event returns to subscriber B, subscriber B can be skipped directly. The TCP connection corresponding to subscriber B can eventually be closed after timeout according to the corresponding network protocol processing.

[0145] Therefore, even if a single target subscriber becomes a zombie subscriber due to abnormal network connection, cancellation can be performed in time after the buffer of the corresponding target private channel reaches a full state, so that the zombie subscriber will no longer affect other healthy subscribers from receiving the output events generated by the target process.

[0146] Optionally, in one embodiment, the scenario of multiple residual subscribers existing after the cloud sandbox is restored is used as an example for illustration.

[0147] The cloud sandbox can sequentially perform pause, create a memory snapshot, and resume operations. Before the cloud sandbox is paused, the target process already has multiple subscribers, each of which receives output events generated by the target process through its corresponding client network connection.

[0148] After a cloud sandbox is paused, a memory snapshot can be created based on its current running state. Subsequently, the cloud sandbox can be restored based on this memory snapshot. Since changes in the state of network connections themselves may not be fully synchronized with the subscription relationship state in the memory snapshot, some subscription relationships established before the restoration may still be retained after the cloud sandbox is restored.

[0149] For example, after the cloud sandbox was restored, the system detected three residual subscribers: subscriber A, subscriber B, and subscriber C. Subscribers A, B, and C were all subscribers who had established subscription relationships before the cloud sandbox was restored, but their corresponding TCP connections were currently in different states.

[0150] Among them, the TCP connection corresponding to subscriber A is still in a normal state, so subscriber A can continue to consume the output events generated by the target process normally.

[0151] The TCP connection corresponding to subscriber B has been closed. For example, if the FIN packet of the network connection corresponding to subscriber B arrives during the creation of a memory snapshot, the subscription relationship corresponding to subscriber B will still exist after the cloud sandbox recovers, but the corresponding TCP connection can no longer carry out the output events of the target process normally.

[0152] The TCP connection corresponding to subscriber C is in the TIME_WAIT state. At this time, the subscription relationship corresponding to subscriber C may still exist, but subscriber C can no longer consume the output events generated by the target process in the same way as a normal active network connection.

[0153] Therefore, both subscriber B and subscriber C can be considered as residual target subscribers who cannot normally consume the target process's output events after the cloud sandbox is restored.

[0154] After the target process resumes operation and continues to generate output events, the generated output events can be written to the source channel corresponding to the target process. After the fan-out coroutine obtains the output events from the source channel, it can sequentially traverse subscriber A, subscriber B, and subscriber C, and perform output event processing according to the current cancellation status of each subscriber and the buffer status of their respective target private channel.

[0155] For subscriber A, since the TCP connection corresponding to subscriber A is normal, the consumer coroutine corresponding to subscriber A can continuously read output events from the target private channel and send the output events to the client corresponding to subscriber A. Therefore, the fan-out coroutine can continuously deliver the output events generated by the target process to the target private channel corresponding to subscriber A.

[0156] For subscriber B, since the TCP connection corresponding to subscriber B has been closed, subscriber B cannot continue to consume output events from the target private channel normally. As the target process continues to generate output events, the unconsumed output events in the target private channel corresponding to subscriber B accumulate, eventually filling the buffer of the target private channel. After the buffer of the target private channel is full, when the fan-out coroutine subsequently performs output event delivery for subscriber B again, it can trigger the default branch in the select statement and perform eviction processing on subscriber B. For example, subscriber B can be set to a canceled state using cancel(), and the target private channel corresponding to subscriber B can be closed using closeCh(), causing the consuming coroutine corresponding to subscriber B to exit the event reading loop for the target private channel.

[0157] For subscriber C, since its TCP connection is in the TIME_WAIT state, subscriber C cannot continue to consume output events generated by the target process in the normal way. As the target process continues to generate output events, the output events in the target private channel corresponding to subscriber C can also continue to accumulate. When the buffer of the target private channel corresponding to subscriber C reaches a full state, the fan-out coroutine can also trigger the default branch. For example, subscriber C can be set to a canceled state using cancel(), and the target private channel corresponding to subscriber C can be closed using closeCh(), causing the consuming coroutine corresponding to subscriber C to exit the event reading loop for the target private channel.

[0158] Figure 3 This is a schematic diagram of the process output fan-out device provided in this application, as shown below. Figure 3 As shown, the device may include: Module 310 is used to acquire output events of the target process; The traversal module 320 is used to traverse each subscriber subscribing to the target process, and for any subscriber traversed, determine any subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

[0159] In one embodiment, the traversal module 320 is specifically used for: Close the cancellation instruction channel associated with the target subscriber; the closed status of the cancellation instruction channel indicates that the target subscriber is in a canceled state; Close the target private channel of the target subscriber, and exit the event reading loop for the target private channel when the consuming coroutine detects that the target private channel is closed.

[0160] In one embodiment, the traversal module 320 is specifically used for: Add a read lock to the subscriber list used to record each subscriber, and obtain the subscriber snapshot corresponding to the subscriber list; Release the read lock; Iterate through each subscriber based on the subscriber snapshot.

[0161] In one embodiment, the device is further used for at least one of the following: In the case of canceling the target subscriber, the target subscriber is set to the canceled state; a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the target subscriber is removed from the subscriber list; When a new subscriber is registered, the source channel corresponding to the target process is obtained, and the closed status of the source channel is checked for the first time. If the first check determines that the source channel is not closed, a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the closed status of the source channel is checked for the second time. If the second check determines that the source channel is not closed, the new subscriber is added to the subscriber list. If the first or second check determines that the source channel is closed, the pre-closed private channel is returned to the caller corresponding to the new subscriber.

[0162] In one embodiment, the device is further configured to: Maintain the subscriber status of each subscriber; the subscriber status includes an active state, a canceled state, and a channel closed state that change sequentially in one direction. If the target subscriber is canceled, the subscriber status of the target subscriber will be updated from active to canceled. If the target private channel is closed, the subscriber status of the target subscriber will be updated from canceled to closed. If the target subscriber is in a closed channel state, stop delivering output events to the target private channel.

[0163] In one embodiment, the device is further configured to: Configure a single-execution control component corresponding to the target subscriber; The single-execution control component controls the target number of operations to close the cancellation instruction channel and close the target private channel.

[0164] In one embodiment, the buffer capacity of the target private channel is a fixed value.

[0165] Figure 4 This is a schematic diagram of the structure of the electronic device provided in this application, such as... Figure 4As shown, the electronic device may include: a processor 410, a communications interface 420, a memory 430, and a communication bus 440, wherein the processor 410, the communications interface 420, and the memory 430 communicate with each other via the communication bus 440. The processor 410 can call logical instructions in the memory 430 to execute the process output fan-out method described in any of the above embodiments, for example including: Obtain the output events of the target process; Iterate through all subscribers to the target process, and for any subscriber encountered, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

[0166] Furthermore, the logical instructions in the aforementioned memory 430 can be implemented as software functional units and, when sold or used as independent products, can be stored in a computer-readable storage medium. Based on this understanding, the technical solution of this application, in essence, or the part that contributes to the prior art, or a part of the technical solution, can be embodied in the form of a software product. This computer software product is stored in a storage medium and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute all or part of the steps of the methods described in the various embodiments of this application. The aforementioned storage medium includes various media capable of storing program code, such as USB flash drives, portable hard drives, read-only memory (ROM), random access memory (RAM), magnetic disks, or optical disks.

[0167] On the other hand, this application also provides a non-transitory computer-readable storage medium storing a computer program thereon, which, when executed by a processor, implements the process output fan-out method described in any of the above embodiments, for example including: Obtain the output events of the target process; Iterate through all subscribers to the target process, and for any subscriber encountered, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

[0168] The device embodiments described above are merely illustrative. The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the modules can be selected to achieve the purpose of this embodiment according to actual needs. Those skilled in the art can understand and implement this without any creative effort.

[0169] Through the above description of the embodiments, those skilled in the art can clearly understand that each embodiment can be implemented by means of software plus necessary general-purpose hardware platforms, and of course, it can also be implemented by hardware. Based on this understanding, the above technical solutions, in essence or the part that contributes to the prior art, can be embodied in the form of a software product. This computer software product can be stored in a computer-readable storage medium, such as ROM / RAM, magnetic disk, optical disk, etc., and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute the methods described in the various embodiments or some parts of the embodiments.

[0170] Finally, it should be noted that the above embodiments are only used to illustrate the technical solutions of this application, and are not intended to limit them. Although this application has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features. Such modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of this application.

Claims

1. A process output fan-out method, characterized in that, The method includes: Obtain the output events of the target process; Iterate through all subscribers to the target process, and for any subscriber encountered, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

2. The process output fan-out method according to claim 1, characterized in that, Setting the target subscriber to a canceled state includes: Close the cancellation instruction channel associated with the target subscriber; the closed status of the cancellation instruction channel indicates that the target subscriber is in a canceled state; Close the target private channel of the target subscriber, and exit the event reading loop for the target private channel when the consuming coroutine detects that the target private channel is closed.

3. The process output fan-out method according to claim 1, characterized in that, The traversal of each subscriber to the target process includes: Add a read lock to the subscriber list used to record each subscriber, and obtain the subscriber snapshot corresponding to the subscriber list; Release the read lock; Iterate through each subscriber based on the subscriber snapshot.

4. The process output fan-out method according to claim 1, characterized in that, It also includes at least one of the following: In the case of canceling the target subscriber, the target subscriber is set to the canceled state; a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the target subscriber is removed from the subscriber list; When a new subscriber is registered, the source channel corresponding to the target process is obtained, and the closed status of the source channel is checked for the first time. If the first check determines that the source channel is not closed, a write lock is added to the subscriber list used to record each subscriber, and after adding the write lock, the closed status of the source channel is checked for the second time. If the second check determines that the source channel is not closed, the new subscriber is added to the subscriber list. If the first or second detection determines that the source channel is closed, the pre-closed private channel is returned to the caller corresponding to the new subscriber.

5. The process output fan-out method according to claim 1, characterized in that, Also includes: Maintain the subscriber status of each subscriber; the subscriber status includes an active state, a canceled state, and a channel closed state that change sequentially in one direction. If the target subscriber is canceled, the subscriber status of the target subscriber will be updated from active to canceled. If the target private channel is closed, the subscriber status of the target subscriber will be updated from canceled to closed. If the target subscriber is in a closed channel state, stop delivering output events to the target private channel.

6. The process output fan-out method according to claim 2, characterized in that, Also includes: Configure a single-execution control component corresponding to the target subscriber; The single-execution control component controls the target number of operations to close the cancellation instruction channel and close the target private channel.

7. The process output fan-out method according to claim 1, characterized in that, The buffer capacity of the target private channel is a fixed value.

8. A process output fan-out device, characterized in that, The device includes: The acquisition module is used to acquire the output events of the target process; The traversal module is used to traverse each subscriber subscribed to the target process, and for any subscriber traversed, determine that subscriber as the target subscriber; If the target subscriber is in an unfollowed state, skip the target subscriber; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is not full, the output event is delivered to the target private channel; If the target subscriber is not in a canceled state and the buffer of the target subscriber's target private channel is full, then set the target subscriber to a canceled state.

9. An electronic device comprising a memory, a processor, and a computer program stored in the memory and running on the processor, characterized in that, When the processor executes the computer program, it implements the process output fan-out method as described in any one of claims 1 to 7.

10. A non-transitory computer-readable storage medium having a computer program stored thereon, characterized in that, When the computer program is executed by the processor, it implements the process output fan-out method as described in any one of claims 1 to 7.