Asynchronous I / O call methods, devices, storage media, and computer equipment in business code

CN122132127BActive Publication Date: 2026-08-14CSC FINANCIAL CO LTD
View PDF 2 Cites 0 Cited by

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2026-01-22
Publication Date
2026-08-14

AI Technical Summary

Technical Problem

[0004]有鉴于此,本申请实施例提供了一种业务代码的异步IO调用方法、装置、存储介质及计算机设备,主要目的在于解决现有的异步IO调用方法的程序可读性和可维护性差、以及对遗留系统进行异步化改造复杂度和成本高的技术问题

Benefits of technology

[0009]借由上述技术方案,本申请实施例提供的一种业务代码的异步IO调用方法及装置、存储介质及计算机设备,首先创建事件驱动的反应堆线程和线程局部资源,并将每个业务请求实例化为包含独立上下文信息和状态变量的请求对象,然后在业务逻辑中利用状态变量标记执行断点并发送非阻塞的异步调用,进而根据状态变量处理响应数据,并在所有响应数据处理完毕后完成响应内容的组装。上述方法可以在每次异步调用时自动创建回调数据对象,并在回调数据对象的对象生命周期结束时驱动业务处理函数以当前的状态变量重新执行,从而实现基于状态变量的业务逻辑自动推进和重入。上述方法可以在完全不改变原有服务框架业务接口的前提下,实现业务逻辑的异步非阻塞执行,从而极大地提高了单线程的IO吞吐量和业务请求的并发处理能力,同时,也保持了业务代码的可读性和可维护性,并降低了对遗留系统进行异步化改造的复杂度和成本。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122132127B_ABST
    Figure CN122132127B_ABST
Patent Text Reader

Abstract

This application discloses an asynchronous I / O call method, apparatus, storage medium, and computer device for business code. The method includes: creating a reactor thread and initializing thread-local resources when the framework starts; creating a request object in response to a detected business request; executing the business process in the business processing function of the request object; switching state variables and calling an asynchronous command sending function when an I / O call operation is executed; creating a callback data object and constructing an asynchronous operation object through the asynchronous command sending function; executing the asynchronous call operation through the asynchronous operation object; the response to the asynchronous call operation drives the business processing function to re-execute with the current state variable after the lifecycle of the callback data object ends; processing response data after the response to the asynchronous call operation returns; and sending the response content after all response data has been processed. This method, through an automatic callback-driven mechanism, enables asynchronous scheduling and non-blocking execution of business logic.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This application relates to the field of computer software engineering technology, and in particular to an asynchronous I / O call method, apparatus, storage medium, and computer device for business code. Background Technology

[0002] With the widespread adoption of microservices and distributed systems, modern server software generally employs a business-oriented programming model. Under this model, developers can write core logic by implementing specific business processing interfaces or inheriting base classes, resulting in concentrated and clearly structured code. However, when business processing involves frequent external I / O operations such as accessing databases or other upstream services, this synchronous processing mode can block the currently executing thread while waiting for external responses. Under conditions of high concurrent request volume or high external service latency, limited thread resources will be heavily consumed, leading to a sharp drop in system throughput and a significant increase in request latency.

[0003] To improve I / O call efficiency, existing technologies typically employ asynchronous programming models to avoid blocking. Current mainstream asynchronous I / O implementations can be categorized into three types: First, schemes based on multithreading and callback functions, which, while leveraging multi-core advantages, are prone to code fragmentation, reducing readability and maintainability; second, schemes based on stack-based coroutines, enabling lightweight thread switching in user space, with a programming model close to synchronous methods, and are widely used, but the stack copying operations during coroutine switching incur performance overhead; and third, schemes based on C++20 standard stackless coroutines, which offer excellent performance but are invasive designs requiring significant modifications to existing business code and framework interfaces, resulting in high migration costs and difficulty in implementation on legacy systems. Summary of the Invention

[0004] In view of this, embodiments of this application provide an asynchronous I / O call method, apparatus, storage medium, and computer device for business code, with the main purpose of solving the technical problems of poor program readability and maintainability of existing asynchronous I / O call methods, as well as the high complexity and cost of asynchronous transformation of legacy systems.

[0005] According to one aspect of this application, an asynchronous I / O call method for business code is provided, the method being used to complete an asynchronous call process in a single reactor thread, the method comprising: When the framework starts, a reactor thread is created and thread-local resources are initialized, including an event scheduler for listening to business requests. In response to a detected business request, a request object for the business request is created based on a unified framework request base class, wherein the request object contains the context information and state variables of the business request; The business process is executed in the business processing function of the request object, and when the business process reaches the IO call operation, the state variable is switched according to the context information and the asynchronous command sending function is called; The asynchronous command sending function creates a callback data object and constructs an asynchronous operation object. The asynchronous operation object is used to execute an asynchronous call operation. The response of the asynchronous call operation drives the business processing function to be re-executed with the current state variable when the life cycle of the callback data object ends. After the response to the asynchronous call operation is returned, the response data is processed according to the current state variable. After all the response data of the asynchronous call operation has been processed, the response content of the business request is constructed and sent.

[0006] According to another aspect of this application, an asynchronous I / O call apparatus for business code is provided, the apparatus being used to complete an asynchronous call process in a single reactor thread, the apparatus comprising: The resource initialization module is used to create a reactor thread and initialize thread-local resources when the framework starts. The thread-local resources include an event scheduler for listening to business requests. The request object creation module is used to respond to a listened business request by creating a request object for the business request based on a unified framework request base class. The request object contains the context information and state variables of the business request. The business process execution module is used to execute the business process in the business processing function of the request object, and when the business process reaches the IO call operation, switch the state variable according to the context information and call the asynchronous command sending function; The asynchronous I / O call module is used to create a callback data object and construct an asynchronous operation object through the asynchronous command sending function, and execute the asynchronous call operation through the asynchronous operation object. The response of the asynchronous call operation drives the business processing function to re-execute with the current state variable when the life cycle of the callback data object ends. The response data processing module is used to process the response data according to the current state variables after the response of the asynchronous call operation is returned, and to construct and send the response content of the business request after all the response data of the asynchronous call operation has been processed.

[0007] According to another aspect of this application, a storage medium is provided on which a computer program is stored, wherein the program, when executed by a processor, implements the asynchronous I / O call method of the above-mentioned business code.

[0008] According to another aspect of this application, a computer device is provided, including a storage medium, a processor, and a computer program stored on the storage medium and executable on the processor, wherein the processor executes the program to implement the asynchronous I / O call method of the above-mentioned business code.

[0009] By employing the above technical solutions, this application provides an asynchronous I / O call method, apparatus, storage medium, and computer device for business code. First, it creates an event-driven reactor thread and thread-local resources, and instantiates each business request as a request object containing independent context information and state variables. Then, in the business logic, it uses state variables to mark execution breakpoints and sends non-blocking asynchronous calls. Subsequently, it processes response data according to the state variables and assembles the response content after all response data has been processed. This method can automatically create callback data objects during each asynchronous call and drive the business processing function to re-execute with the current state variables when the callback data object's lifecycle ends, thereby achieving automatic advancement and re-entry of business logic based on state variables. This method can achieve asynchronous non-blocking execution of business logic without changing the original service framework's business interface, thus greatly improving the I / O throughput of a single thread and the concurrent processing capability of business requests. At the same time, it maintains the readability and maintainability of the business code and reduces the complexity and cost of asynchronous transformation of legacy systems.

[0010] The above description is only an overview of the technical solution of this application. In order to better understand the technical means of this application and to implement it in accordance with the contents of the specification, and to make the above and other objects, features and advantages of this application more obvious and understandable, the following are specific embodiments of this application. Attached Figure Description

[0011] The accompanying drawings, which are included to provide a further understanding of this application and form part of this application, illustrate exemplary embodiments and are used to explain this application, but do not constitute an undue limitation of this application. In the drawings: Figure 1 A flowchart illustrating an asynchronous I / O call method for business code provided in an embodiment of this application is shown. Figure 2 A schematic diagram of the structure of an asynchronous I / O call device for business code provided in an embodiment of this application is shown. Detailed Implementation

[0012] The present application will be described in detail below with reference to the accompanying drawings and embodiments. It should be noted that, unless otherwise specified, the embodiments and features described in the embodiments of the present application can be combined with each other.

[0013] In one embodiment, such as Figure 1As shown, an asynchronous I / O call method for business code is provided. This method can complete the asynchronous call process in a single reactor thread. The following steps are illustrated using the application of the above method in a C++ programming environment for computer devices: Step 101: When the framework starts, create a reactor thread and initialize thread-local resources, including an event scheduler for listening to business requests.

[0014] In this framework, the reactor thread refers to an independent worker thread running an event loop, whose core function is to listen for and process all registered I / O events. Thread-local resources refer to a set of data structures allocated exclusively to this thread, primarily including an event scheduler. The event scheduler is an instance of an event loop manager, responsible for uniformly listening to all event sources such as network connections and timers. In this embodiment, the framework runs on top of the reactor thread, and the entire framework consists of only one thread. Based on this, this embodiment can complete the entire asynchronous call process in a single thread, and also supports horizontal scaling of the above methods to multiple threads. It should be noted that in multi-threaded scenarios, there is no communication between the multiple threads, and thread pools, mutexes, etc., are not included, which is a key difference from other frameworks.

[0015] Specifically, during the server program startup phase, one or more threads for event handling, i.e., reactor threads, can be created. For each such thread, a thread-local resource can be allocated, which can be represented by a structure, such as a structure named `thread_aux`. This structure must contain at least one `event_base`. Members of this type serve as event schedulers. During the initialization of thread-local resources, an event scheduler instance can be created first, and server listening sockets, pre-connected sockets to external services such as Redis and upstream HTTP services, and health check timers can be registered to this event scheduler, enabling the event scheduler to listen for incoming business requests in real time.

[0016] In this embodiment, one or more reactor threads can be created, each capable of independently completing the entire asynchronous I / O call and business logic scheduling process. For simplicity, this embodiment uses the creation of one reactor thread as an example. It is understood that, to further expand I / O throughput and the concurrent processing capability of business requests, this method can be replicated to multiple parallel-running threads. Each thread has independent thread-local resources and does not communicate with others, thereby jointly processing business requests sent by the client.

[0017] Step 102: In response to the detected business request, a request object for the business request is created based on the unified framework request base class. The request object contains the context information and state variables of the business request.

[0018] Here, the framework request base class refers to the public abstract class defined by service frameworks such as the HTTP server framework, which all business handlers must inherit from. The request object refers to the handler object instantiated for this business request, which inherits from the aforementioned framework request base class. Context information includes the raw request data received from the client and the data structures prepared for calling external services. State variables refer to enumerated values ​​used to identify the current execution progress of the business logic.

[0019] Specifically, after the event scheduler detects a new client connection and completes the parsing of the business request, it can determine the business type corresponding to the request based on characteristics such as the request path. Subsequently, an instance of the processing class corresponding to that business type can be dynamically created, i.e., a request object can be created. During creation, client request parameters, protocol information, and other parameters parsed from the business request can be filled into the member variables of the request object to constitute the client request context information. Simultaneously, a storage area for recording command identifiers and response data for asynchronous calls is initialized to constitute the third-party service request context information. Furthermore, a state variable can be initialized and set to its initial state. This embodiment, by abstracting a business request into a request object with a complete lifecycle and independent execution context, provides an execution carrier for subsequent implementation of interruptible and recoverable asynchronous business processing flows.

[0020] Step 103: Execute the business process in the business processing function of the request object, and when the business process reaches the IO call operation, switch the state variable according to the context information and call the asynchronous command sending function.

[0021] Here, "business processing function" refers to the unified interface function defined by the framework's request base class and implemented by the request object, which can be used to write core business logic. "State variable switching" refers to the process of updating the request object's internal state variables based on the event type that the next step in the business logic needs to wait for. "Asynchronous command sending function" is a wrapper method provided by the framework, which can be used to initiate non-blocking calls to external services.

[0022] Specifically, after the request object is created, its business processing function is automatically invoked. This function typically uses a switch-case logic based on a state variable. Upon initial entry, the state variable is in its initial state, and code in this initial state, such as parameter parsing, is executed. When the logic requires access to an external service like Redis, the state variable switches to a state of waiting for the service's response. Then, an asynchronous command sending function, such as `RedisCommand`, is called, passing in the command parameters. The asynchronous command sending function immediately returns a unique command identifier for this call. After sending one or more such asynchronous commands, the business processing function breaks and returns to the framework; the thread is not blocked. Each time the business process reaches an I / O call, it can switch the state variable based on context information. The state variable is updated again when the business process corresponding to the current state variable has completed and the next step is required, until the state variable is updated to the completion state.

[0023] This embodiment sets up a state machine pattern based on state variables, which allows business logic to pause when it encounters an I / O call and delegate the subsequent execution drive to the upcoming I / O response callback. This transforms linear business logic into a phased, non-blocking process, allowing thread control to be released immediately while waiting for external I / O, thereby improving thread utilization and the system's concurrent processing capabilities.

[0024] Furthermore, in this embodiment, when the business process reaches a certain state, such as waiting for a Redis response, the asynchronous command sending function can be called continuously or in batches in this state according to the needs of the business logic. This allows multiple asynchronous I / O requests to be initiated at once, such as sending multiple query commands to Redis or initiating HTTP requests to upstream services simultaneously. Each time the asynchronous command sending function is called, a unique command identifier can be allocated from thread-local resources and bound to this I / O call operation. These asynchronous requests can be sent in parallel, and their responses may be returned out of order. Each response carries its corresponding command identifier. When the response returns and triggers the re-execution of the business processing function, the business logic can accurately identify the request to which the response belongs based on the command identifier and extract the corresponding response data from the response storage area of ​​the request object for processing. This mechanism enables the concurrent sending and processing of multiple I / O requests within the same business processing stage, thereby achieving concurrency within the business logic and further improving processing efficiency.

[0025] Compared to traditional asynchronous I / O frameworks where business logic is still executed serially—meaning the next asynchronous request must wait for the previous one to return before it can be initiated—this method supports concurrent initiation and independent callbacks of batch asynchronous requests within the same state, thus achieving a highly efficient "one thread, batch requests" model. This not only retains the advantages of asynchronous non-blocking but also further reduces idle time caused by I / O waiting through in-business concurrency mechanisms, significantly improving the utilization of a single thread and the overall system throughput.

[0026] Step 104: Create a callback data object and construct an asynchronous operation object through the asynchronous command sending function, and execute the asynchronous call operation through the asynchronous operation object.

[0027] In this context, the callback data object is a small, dynamically created structure on the heap used to associate the asynchronous call operation with the original request object. The asynchronous operation object is a temporary object encapsulating information such as the target connection, command data, and callback function. In this embodiment, the response to the asynchronous call operation drives the business processing function to re-execute with the current state variables upon the end of the callback data object's lifecycle.

[0028] Specifically, when executing the asynchronous command sending function, the command string is first formatted, and then an incrementing unique command identifier is obtained from thread-local resources. Next, a callback data object is created, and the command identifier and the address pointer of the current request object are stored in the callback data object. In this embodiment, the destructor of the callback data object is defined as calling the business processing function of the request object. The destructor of the callback data object refers to the function automatically called when the lifetime of the callback data object ends. Taking a Redis query operation as an example, when constructing the asynchronous operation object, a pre-established Redis connection context, a formatted command string, a user-level callback function, and the address pointer of the aforementioned callback data object can be passed as parameters. Finally, this operation can be submitted for execution through a low-level asynchronous library such as libevent, and the command identifier is returned to the caller. When the Redis response has not yet arrived, the system's underlying callback function is triggered. This callback parses the response through the callback function and uses the callback data object pointer to call its response setting function to store the response data into the request object. Subsequently, the callback data object is destructed, automatically triggering the request object's business processing function to be called again, thereby driving the business logic to continue execution. In this embodiment, since each asynchronous call operation corresponds to an independent callback data object, and the callback data object can be destructed immediately after the response processing is completed, there will be no nested or recursive calls of callback functions, thus ensuring the clarity and safety of the call stack.

[0029] This embodiment designs an intelligent callback chain mechanism that utilizes the RAII (Resource Acquisition and Initialization) principle. This ensures that asynchronous IO responses can automatically and accurately drive the corresponding business logic to resume execution, thereby enabling the suspension and automatic resumption of business logic, while ensuring precise matching between business requests and response data.

[0030] Step 105: After the response of the asynchronous call operation is returned, process the response data according to the current state variable. After all the response data of the asynchronous call operation has been processed, construct and send the response content of the business request.

[0031] Specifically, after the callback data object destruction triggers the business processing function to execute again, the business processing function first checks the state variables stored inside the request object. For example, if the state variables were previously set to wait for a Redis service response when the Redis query was initiated, the code will jump to the corresponding processing branch. In this branch, the business processing function retrieves the command identifier corresponding to the most recently received response, then extracts the corresponding response data from the request object's storage area based on the command identifier, and executes the subsequent business logic designed for that command, such as data transformation and combination. After processing is complete, it checks whether the responses to all asynchronous commands that this business request depends on have been returned and processed. If there are still unfinished commands, the business processing function returns directly, keeping the state variable unchanged, and continues to wait. If the business process in the current state has been completed, and there are other IO calls in the business processing function, the state variable is updated again and the asynchronous command sending function is called when the next IO call is executed, i.e., steps 103 to 105 are repeated. If all responses have been processed, i.e., the business process in the current state has been completed and the business processing function has also been completed, the state variable is updated to the completed state, and based on the processing results of all response data, the final response content is combined, and the framework's response sending interface is called to return the data to the client. After sending, the current request object is destroyed to release all resources.

[0032] This embodiment, by setting up a state machine and command identifier mechanism, can process multiple asynchronous responses that may arrive out of order in an orderly and correct manner, and end the lifecycle of the business request after all tasks are completed, so as to ensure the integrity of the business and the timely recovery of resources.

[0033] The above embodiments first create event-driven reactor threads and thread-local resources, and instantiate each business request as a request object containing independent context information and state variables. Then, in the business logic, execution breakpoints are marked using state variables, and non-blocking asynchronous calls are sent. Response data is then processed based on the state variables, and the response content is assembled after all response data has been processed. This method automatically creates callback data objects with each asynchronous call and drives the business processing function to re-execute with the current state variables when the callback data object's lifecycle ends, thus achieving automatic advancement and re-entry of business logic based on state variables. This method can achieve asynchronous non-blocking execution of business logic without changing the original service framework's business interface, thereby greatly improving single-threaded IO throughput and concurrent processing capabilities for business requests. At the same time, it maintains the readability and maintainability of the business code and reduces the complexity and cost of asynchronous transformation of legacy systems.

[0034] In one embodiment, step 101 can be performed as follows: First, when the framework starts, a reactor thread is created and the event scheduler in the thread-local resources is initialized. Then, network connections and database connections are established through the event scheduler, and the network connection information and database connection information are registered to the event scheduler for periodic monitoring. Finally, the server listening port is registered to the event scheduler, the command identifier numberer is initialized, and the event listening loop is started to listen for business requests.

[0035] Specifically, upon framework startup, a thread for event listening, known as the reactor thread, is first created, and its private thread-local resources are initialized. The core of this initialization is the creation of an event scheduler instance. This event scheduler can then be used to establish network connections with external services such as remote databases and upstream HTTP interfaces, registering these connection handles with the event scheduler. Simultaneously, periodic health check tasks can be set for these connections to continuously monitor their validity. Next, the listening port used by the service program to receive client requests can also be registered with the same event scheduler, and a thread-unique command identifier counter is initialized and set to its initial value. After all registrations are complete, the event scheduler's event loop can be started, allowing the event scheduler to continuously listen for events on all registered objects.

[0036] For example, the thread-local resources of a reactor thread can be represented by the following structure: thread_local thread_aux __thd_d__; struct thread_aux { struct event_base _base; std::variant <evhttp evhtp >_http_base; std::shared_ptr<redis_context> _redis_ctx; size_t _cmd_id; ... }; Specifically, the `thread_aux` structure is the thread-local resource of the reactor thread, encapsulating its core resources. Within this structure, the `_base` member is the event scheduler, the core of all event listening and processing; the `_http_base` and `_redis_ctx` members represent the pre-established network connection contexts with external HTTP services and the Redis database, respectively; and the `_cmd_id` member is a command identifier numberer used to generate a unique identifier for each asynchronous I / O call issued within the thread.

[0037] During the framework startup phase, a reactor thread is first created, and its private `thread_aux` resource structure is initialized. The specific process includes: creating a `_base` event scheduler instance; initializing `_http_base` and `_redis_ctx`, establishing network connections with the corresponding external services, and registering these connection handles and their health check timers to the `_base` scheduler; registering the server's own listening socket to `_base` to receive business requests from clients; and finally, initializing the `_cmd_id` command identifier numberer to 0 and starting the `_base` event scheduler's event listening loop, thus beginning to listen for all events registered to it and preparing for processing business requests.

[0038] The above embodiments, by pre-completing the construction of reactor threads, the establishment and health monitoring of external service connections, and the initialization of command identifiers during the framework startup phase, can provide the system with a stable, efficient, and self-maintaining event-driven processing foundation, thereby ensuring that subsequent business requests can be responded to in a timely manner. At the same time, calls to external services also have available connection channels and request tracing capabilities.

[0039] In one embodiment, step 102 can be performed as follows: In response to a business request being detected, firstly, the business type is determined based on the feature information carried in the business request, and a request object corresponding to the business type is created based on a unified framework request base class. Then, the client request context information is extracted from the business request, and the third-party service request context information and state variables corresponding to the business type are initialized. The state values ​​of the state variables include an initial state, at least one IO response waiting state, and a completion state. Finally, the business processing function of the request object is called, and the business process is executed in the business processing function based on the current state variables.

[0040] Specifically, after the event scheduler detects a new business request, it first parses the request and maps it to a predefined business type, such as user query or file upload, based on its URL path, method, and other characteristics. Then, it dynamically instantiates a request object corresponding to that business type, inheriting from a unified framework request base class. Next, it extracts information such as the client IP and request parameters from the parsed request and stores this as the client request context in the request object. Simultaneously, it initializes a storage area for storing asynchronous call command identifiers, response data, and other information, serving as the third-party service request context, according to the needs of the business type. Then, it initializes the request object's internal state variables to their initial state. The preset state values ​​for these variables include the initial state, various IO response waiting states for different external services, and a completion state. Finally, it automatically calls the request object's business processing function. This function jumps to the corresponding code segment based on the current state variable value to begin executing the business process; for example, in the initial stage, execution begins with the code corresponding to the initial state.

[0041] For example, in the business logic implementation file, the state values ​​of the following state variables can be defined: enum uuHandlerState { INIT = 0, REDIS_REPLY, HTTP_REPLY, HTTPS_REPLY, DONE }; The request object internally defines a state enumeration `uuHandlerState`, which includes the initial state `INIT`, the waiting state `REDIS_REPLY` for Redis responses, the waiting states `HTTP_REPLY` and `HTTPS_REPLY` for HTTP and HTTPS responses, and the completion state `DONE`. After the request object is created, its internal state variable `_state` is set to `INIT`. The framework then automatically calls the request object's business processing function `handler`, which begins executing the corresponding business process based on the current value of `_state`.

[0042] The above embodiments instantiate business requests into a request object containing context information and state variables, which can provide an independent execution carrier and progress indicator for business processing. This enables the originally linear business logic to be executed in a state-driven manner, laying the foundation for subsequent non-blocking asynchronous I / O calls within a single thread. At the same time, it also ensures the readability and maintainability of the business code.

[0043] In one embodiment, step 103 can be performed as follows: First, in the business processing function of the request object, the business process corresponding to the initial state is executed. Then, the following steps are executed in a loop: After the business process reaches the IO call operation and the business process of the previous state is completed, the state variable is set to the next state according to the context information, and the asynchronous command sending function is called; at least one IO command is sent through the asynchronous command sending function and returned immediately, wherein each IO command corresponds to a command identifier, and the command identifier is maintained in thread-local resources.

[0044] Specifically, after the request object is created and its business processing function is automatically invoked, the business processing function first checks the value of the state variable. If the state variable is in the initial state, the preset business initialization logic in that state is executed. When this logic is completed and an external I / O call needs to be initiated, such as a database query, the next response type to wait for is determined based on business requirements, and the state variable is updated to the corresponding I / O response waiting state, such as the Redis response waiting state, thus recording the breakpoint of the business execution. Subsequently, the asynchronous command sending function can be called to execute the actual I / O operation. The asynchronous command sending function uses a unique command identifier generator maintained in thread-local resources to assign unique command identifiers to multiple I / O commands that may be sent consecutively in this and subsequent calls, and sends the commands non-blockingly through a pre-established connection. After that, the function returns immediately. After sending the command, the business processing function also completes its call and returns, and the thread is immediately released to handle other tasks.

[0045] For example, the code snippet in the business processing function is as follows: switch (_state) { case uuHandlerState::INIT: dump_req(); / / Business logic, simulated here by printing requests. _state = uuHandlerState::REDIS_REPLY; id1 = RedisCommand <std::string>("get %s", "STR_redis_num_6379"); / / Set id1 as an object member id2 = RedisCommand <std::string>("get %s", "STR_redis_num_6379"); / / Set id2 as an object member break; / / Return Specifically, when the request object's business processing function `handler` is called for the first time, the state variable `_state` is set to `uuHandlerState::INIT`. At this point, the business logic corresponding to the `INIT` state is executed, such as calling the `dump_req()` function to record the request log. After this logic is completed, if the subsequent business process needs to access Redis, `_state` is set to the next state `uuHandlerState::REDIS_REPLY` to indicate that the business is entering a phase of waiting for a Redis response. Subsequently, the asynchronous command sending function `RedisCommand` is called consecutively, passing in the command template `get %s` and the parameter `STR_redis_num_6379` to send commands to the Redis server to retrieve data. Each call to the `RedisCommand` function immediately returns a unique command identifier `cmdid`, which is obtained from thread-local resources and incremented. This identifier is stored in the request object's member variables `id1` and `id2`. After sending all necessary I / O commands, the handler function terminates its execution and returns using a break statement. At this point, the thread is immediately released and can switch to handling other requests or waiting for events, while the current business logic is suspended and waiting for a response.

[0046] This embodiment introduces a state variable-based breakpoint control and asynchronous command sending mechanism into the business processing function, which enables a single thread to immediately withdraw when encountering time-consuming I / O operations by simply switching the state variable and issuing a request. This achieves non-blocking progress of business logic and greatly improves the utilization rate of threads in intensive I / O scenarios and the overall throughput of the system.

[0047] In one embodiment, step 104 can be performed as follows: First, within the asynchronous command sending function, the command template and parameters passed by the business processing function are received, and the command template and parameters are combined to generate a command string. Then, the command identifier is obtained from the thread-local resources, and a callback data object is created, wherein the callback data object stores the command identifier and the address pointer of the request object. Next, a callback function is defined, and the callback data object is associated with the callback function as a parameter. The callback function is automatically executed when the response of the asynchronous call operation arrives. Further, the connection channel information, command string, callback function, and callback data object registered in the thread-local resources are combined to construct an asynchronous operation object. Finally, the asynchronous call operation is executed through the asynchronous operation object, and the obtained command identifier is returned to the business processing function.

[0048] Specifically, when the asynchronous command sending function is invoked, it first receives the raw command and parameters from the business processing function and combines them into a complete command string. Then, it obtains a globally incrementing unique command identifier from the current thread's local resource structure and dynamically creates a callback data object using this command identifier and the address pointer of the current request object as parameters. Next, it defines a callback function that is automatically executed by the system when the IO response arrives and associates the created callback data object as user data with this callback function. Afterward, the callback function obtains a pre-established and registered external service connection channel, such as a Redis asynchronous connection context, from the thread's local resources and combines it with the formatted command string, the defined callback function, and its associated callback data object to construct a complete asynchronous operation object. Finally, it submits a non-blocking IO call request to the external service through this asynchronous operation object and immediately returns the command identifier allocated for this call to the upper-level business processing function.

[0049] For example, the code snippet for the asynchronous command sending function is as follows: template<typename RET, typename ... Args> size_t RedisCommand(const std::string&cmd, Args ... args) { redis_operation <ret>rop{__thd_d__._redis_ctx, string_format(cmd,args...), [](struct redisAsyncContext actx, void reply, void pcb_data) { std::unique_ptr<pcb_data_t <ret>> pd(reinterpret_cast<pcb_data_t <ret> >(pcb_data)); pd->set_reply(redis_operation <ret>::deal_redis_reply((redisReply )reply)); }, (void )new pcb_data_t <ret>{this} }; return __thd_d__._cmd_id; } template<typename T> struct pcb_data_t { size_t _reply_id; HttpHandler _hdler; pcb_data_t(HttpHandler h) : _reply_id(++__thd_d__._cmd_id), _hdler(h){} void set_reply(std::optional <t>reply) { _hdler->set_reply(_reply_id, std::move(reply)); } ~pcb_data_t() { _hdler->handler(); } When the business processing function calls the RedisCommand function, the function first receives the command template (cmd, such as get %s) and variable arguments (args, such as STR_redis_num_6379), and formats them into a complete command string using string_format. Next, the function retrieves the Redis connection context _redis_ctx from the thread-local resource __thd_d__ and increments the command identifier _cmd_id to generate a unique ID for this call. The core operation involves creating a callback data object of type pcb_data_t. This object's constructor stores the newly generated command identifier _reply_id and a pointer to the current request object _hdler. Its set_reply method stores the response, and the destructor is designed to automatically call the request object's business processing function to resume business execution. Subsequently, a user-level callback function is defined, which is triggered when the Redis response arrives. This callback function is responsible for parsing the response data and calling the set_reply method of its associated callback data object. Finally, the function combines the Redis connection context, the formatted command string, the defined callback function, and the pointer to the newly created callback data object to construct an asynchronous operation object of type redis_operation, and submits a non-blocking I / O call to the Redis server through this asynchronous operation object, and immediately returns the allocated command identifier to the caller.

[0050] This embodiment constructs an asynchronous operation object that integrates commands, connections, callback functions, and callback data objects, enabling accurate encapsulation and dispatch of asynchronous I / O requests. Furthermore, the callback data object can bind the current I / O operation to the request object that initiated the business request and a unique command identifier, thus laying the foundation for accurate subsequent response returns and automatic triggering of business logic recovery.

[0051] In one embodiment, in step 105, the response data can be processed as follows: When the response to the asynchronous call operation returns, the business processing function of the request object is re-executed, and the user jumps to the corresponding processing logic block in the business processing function based on the current state variable. Within the processing logic block, the command identifier corresponding to the currently returned response is obtained, and the corresponding response data is extracted from the response storage area of ​​the request object based on the command identifier. Then, the corresponding asynchronous call operation is determined based on the command identifier, and the business process related to the command identifier within the processing logic block is executed to process the response data.

[0052] Specifically, after the response to the asynchronous call operation is returned via the network, the event scheduler captures and triggers a pre-registered callback process. This process drives the corresponding request object's business processing function to be invoked again. When the business processing function executes, it first reads the current state variable stored internally by the request object and jumps to the matching processing logic block within the business processing function based on the state variable. Within this logic block, the unique command identifier bound to this response can be obtained. Then, using this command identifier as a key, the pre-stored response data is retrieved from the response storage area maintained internally by the request object. Next, the business logic can determine which specific I / O operation it is based on the command identifier, and then execute the subsequent data processing code associated with that command identifier, thereby completing the business logic processing of this response data.

[0053] For example, the code snippet in the business processing function is as follows: switch (_state) { case uuHandlerState::REDIS_REPLY: size_t id = ReplyID(); std::string reply = Reply <std::string>(); if(id == id1)... else ... break; / / Return ... Specifically, when the asynchronous I / O response returns, the request object's business processing function `handler` is invoked again, driven by the `pcb_data_t` destructor. At this point, the function checks its state variable `_state`. If it was previously set to `uuHandlerState::REDIS_REPLY`, the corresponding case branch is executed. Within this processing logic block, `ReplyID()` is first called to obtain the unique command identifier `id` corresponding to the currently arriving response, and then `Reply()` is called... <std::string>The `reply` function retrieves the parsed string-type response data from the response storage area within the request object based on this identifier. Then, by comparing the `id` with the original command identifiers stored in the request object members, such as `id1` and `id2`, it determines which previously issued Redis command this response corresponds to and executes the related subsequent business logic, such as storing the data in a specific variable.

[0054] This embodiment automatically acquires status variables when a response arrives and uses command identifiers to achieve accurate matching and targeted processing of response data with business requests. This ensures that multiple IO responses that may arrive out of order can be processed in an orderly and correct manner in a single-threaded asynchronous environment. At the same time, it can also drive business logic to continue execution from the exact position of the last interruption, thereby ensuring the reliable execution of the asynchronous processing flow.

[0055] In one embodiment, in step 105, the response content can be generated as follows: After the current response data has been processed, the response status of all asynchronous call operations on which the business request depends is checked based on the sent command identifier and the processed command identifier. If there are any unreturned or unprocessed responses, the current state variable remains unchanged, the business processing function finishes execution and returns, and continues to wait for subsequent responses; if it is confirmed that the responses of all asynchronous call operations have been returned and processed, the response content of the business request is generated by combining all processed response data. Then, the response sending method provided by the framework is called to return the response content to the client corresponding to the business request, and the request object of the business request is destroyed after the response content is sent.

[0056] Specifically, after processing the response to an asynchronous I / O call, the system queries the list of sent command identifiers recorded in the request object and compares it with the list of successfully processed response identifiers to check whether all external I / O calls dependent on this business request have been processed. If the comparison finds that there are still command responses that have not been returned or processed, the state variables inside the request object will remain unchanged, the business processing function will return directly after this call, and the system will continue to wait for subsequent responses. Once it is confirmed that all associated I / O responses have been returned and processed, all processed response data will be integrated and formatted according to business logic to generate the final response content returned to the client. Subsequently, the service framework's built-in response sending interface will be called to send this response content back to the client that initiated the request. After successful sending, a cleanup process will be executed, and the request object instance representing this business request will be destroyed to release all memory and system resources it occupies.

[0057] For example, the code snippet for the response sending method is as follows: void SendResponse() { _req->SetResponseCode(200); _req->SetResponseAttr("Content-Type", "text / html; charset=UTF-8"); _req->SendResponse(); delete this; } Specifically, after processing the current response, if it is determined that there are still responses to other sent commands that have not yet returned (e.g., the response to id1 has been processed, but the response to id2 has not yet arrived), the state variable _state remains unchanged, the function returns via break, and continues to wait. Once it is confirmed that all associated IO responses have been processed, the request object calls the base class's SendResponse function. This function sets the HTTP response status code to 200, sets response attributes such as content type, and finally sends the combined business data back to the client. At the end of the SendResponse function's execution, the request object self-destructs using the delete this; statement. Its occupied memory, along with all resources such as the client request context and third-party service request context, are released, marking the end of the lifecycle of this business request.

[0058] This embodiment ensures the integrity of business logic by checking the completion status of all asynchronous operations at the end of execution and triggering the assembly and sending of the response only after all operations are completed. Simultaneously, by binding the destruction of the request object to the successful sending of the response, automatic resource reclamation can be achieved, thereby avoiding resource leaks and improving the stability and resource utilization of the system when handling a large number of concurrent requests.

[0059] It should be noted that the user information (including but not limited to user device information, user personal information, etc.) and data (including but not limited to data used for analysis, stored data, displayed data, etc.) involved in this application are all information and data authorized by the user or fully authorized by all parties. In addition, the labels corresponding to each step in the above embodiments are only for identification purposes and are not intended to limit the execution order of the steps. The execution order of the steps in each embodiment can be set according to the actual situation.

[0060] Furthermore, as Figure 1 In a specific implementation of the method, this application provides an asynchronous I / O call device for business code. This device is used to complete the asynchronous call process within a single reactor thread, such as... Figure 2 As shown, the device includes: Resource initialization module 21 is used to create a reactor thread and initialize thread-local resources when the framework starts, wherein the thread-local resources include an event scheduler for listening to business requests. The request object creation module 22 is used to create a request object for the business request based on a unified framework request base class in response to a business request being listened to. The request object contains the context information and state variables of the business request. Business process execution module 23 is used to execute the business process in the business processing function of the request object, and when the business process reaches the IO call operation, switch the state variable according to the context information and call the asynchronous command sending function; The asynchronous I / O call module 24 is used to create a callback data object and construct an asynchronous operation object through the asynchronous command sending function, and execute an asynchronous call operation through the asynchronous operation object. The response of the asynchronous call operation drives the business processing function to be re-executed with the current state variable when the life cycle of the callback data object ends. The response data processing module 25 is used to process the response data according to the current state variable after the response of the asynchronous call operation is returned, and to construct and send the response content of the business request after all the response data of the asynchronous call operation has been processed.

[0061] In specific application scenarios, the resource initialization module 21 can be used to create a reactor thread and initialize the event scheduler in the thread-local resources when the framework starts; establish network and database connections through the event scheduler and register the network connection information and database connection information to the event scheduler for periodic monitoring; register the server listening port to the event scheduler, initialize the command identifier numberer, and start the event listening loop to listen for business requests.

[0062] In specific application scenarios, the context information includes client request context information and third-party service request context information; the request object creation module 22 can be used to respond to a listened-to business request, determine the business type based on the feature information carried in the business request, and create a request object corresponding to the business type based on a unified framework request base class; extract the client request context information from the business request, and initialize the third-party service request context information and state variables corresponding to the business type, wherein the state values ​​of the state variables include an initial state, at least one IO response waiting state, and a completion state; call the business processing function of the request object, and execute the business process according to the current state variables in the business processing function.

[0063] In a specific application scenario, the business process execution module 23 can be used to execute the business process corresponding to the initial state in the business processing function of the request object; and to repeatedly execute the following steps: after the business process reaches the IO call operation and the business process of the previous state is completed, the state variable is set to the next state according to the context information, and the asynchronous command sending function is called; at least one IO command is sent through the asynchronous command sending function and returned immediately, wherein each IO command corresponds to a command identifier, and the command identifier is maintained in the thread-local resources.

[0064] In a specific application scenario, the asynchronous I / O call module 24 can be used within the asynchronous command sending function to receive the command template and parameters passed by the business processing function, and combine the command template and parameters to generate a command string; obtain the command identifier from the thread-local resources and create a callback data object, wherein the callback data object stores the command identifier and the address pointer of the request object; define a callback function, and associate the callback data object as a parameter into the callback function, wherein the callback function is automatically executed when the response of the I / O call operation arrives; combine the connection channel information registered in the thread-local resources, the command string, the callback function, and the callback data object to construct the asynchronous operation object; execute the asynchronous call operation through the asynchronous operation object, and return the obtained command identifier to the business processing function.

[0065] In a specific application scenario, the response data processing module 25 can be used to re-execute the business processing function of the request object when the response of the asynchronous call operation is returned, and jump to the corresponding processing logic block in the business processing function according to the current state variable; within the processing logic block, obtain the command identifier corresponding to the currently returned response, and extract the corresponding response data from the response storage area of ​​the request object according to the command identifier; determine the corresponding asynchronous call operation based on the command identifier, and execute the business process related to the command identifier within the processing logic block to process the response data.

[0066] In specific application scenarios, the response data processing module 25 can be used to check the response status of all asynchronous call operations on which the business request depends, based on the sent command identifier and the processed command identifier, after the current response data processing is completed. If there are any unreturned or unprocessed responses, the current status variable is kept unchanged, the business processing function finishes execution and returns to continue waiting for subsequent responses. If it is confirmed that the responses of all asynchronous call operations have been returned and processed, the response content of the business request is generated by combining all processed response data. The response sending method provided by the framework is called to return the response content to the client corresponding to the business request, and the request object of the business request is destroyed after the response content is sent.

[0067] It should be noted that other corresponding descriptions of the functional units involved in the asynchronous I / O call device for business code provided in this application embodiment can be found in the following references. Figure 1 The corresponding descriptions in the methods shown will not be repeated here.

[0068] This application also provides a computer device, specifically a personal computer, server, network device, etc. The computer device includes a bus, processor, memory, and communication interface, and may also include input / output interfaces and a display device. The processor of the computer device provides computing and control capabilities. The memory of the computer device includes a non-volatile storage medium and internal memory. The non-volatile storage medium stores an operating system, computer programs, and a database. The internal memory provides an environment for the operation of the operating system and computer programs in the non-volatile storage medium. The database of the computer device stores location information. The network interface of the computer device is used for communication with external terminals via a network connection. When the computer program is executed by the processor, it implements the steps in the various method embodiments.

[0069] Those skilled in the art will understand that the structure of the computer device described above is only a partial structure related to the solution of this application, and does not constitute a limitation on the computer device to which the solution of this application is applied. A specific computer device may include more or fewer components, or combine certain components, or have different component arrangements.

[0070] In one embodiment, a computer-readable storage medium is provided, which may be non-volatile or volatile, having stored thereon a computer program that, when executed by a processor, implements the steps in the above method embodiments.

[0071] In one embodiment, a computer program product is provided, including a computer program that, when executed by a processor, implements the steps in the above method embodiments.

[0072] Those skilled in the art will understand that all or part of the processes in the above embodiments can be implemented by a computer program instructing related hardware. The computer program can be stored in a non-volatile computer-readable storage medium. When executed, the computer program can include the processes of the embodiments described above. Any references to memory, databases, or other media used in the embodiments provided in this application can include at least one of non-volatile and volatile memory. Non-volatile memory can include read-only memory (ROM), magnetic tape, floppy disk, flash memory, optical memory, high-density embedded non-volatile memory, resistive random access memory (ReRAM), magnetic random access memory (MRAM), ferroelectric random access memory (FRAM), phase change memory (PCM), graphene memory, etc. Volatile memory can include random access memory (RAM) or external cache memory, etc. By way of illustration and not limitation, RAM can take many forms, such as Static Random Access Memory (SRAM) or Dynamic Random Access Memory (DRAM). The databases involved in the embodiments provided in this application may include at least one type of relational database and non-relational database. Non-relational databases may include, but are not limited to, blockchain-based distributed databases. The processors involved in the embodiments provided in this application may be general-purpose processors, graphics processors, digital signal processors, programmable logic devices, quantum computing-based data processing logic devices, etc., and are not limited to these.

[0073] The technical features of the above embodiments can be combined in any way. For the sake of brevity, not all possible combinations of the technical features in the above embodiments are described. However, as long as there is no contradiction in the combination of these technical features, they should be considered to be within the scope of this specification.

[0074] The embodiments described above are merely illustrative of several implementation methods of this application, and while the descriptions are specific and detailed, they should not be construed as limiting the scope of this patent application. It should be noted that those skilled in the art can make various modifications and improvements without departing from the concept of this application, and these all fall within the protection scope of this application. Therefore, the protection scope of this application should be determined by the appended claims.< / std::string> < / std::string> < / t> < / ret> < / ret> < / ret> < / ret> < / ret> < / std::string> < / std::string>

Claims

1. An asynchronous I / O call method for business code, characterized in that, The method is used to complete an asynchronous call process within a single reactor thread, and the method includes: When the framework starts, a reactor thread is created and thread-local resources are initialized, including an event scheduler for listening to business requests. In response to a detected business request, a request object for the business request is created based on a unified framework request base class, wherein the request object contains the context information and state variables of the business request; The business process is executed in the business processing function of the request object, and when the business process reaches the IO call operation, the state variable is switched according to the context information and the asynchronous command sending function is called; The asynchronous command sending function creates a callback data object and constructs an asynchronous operation object. The asynchronous operation object is used to execute an asynchronous call operation. The response of the asynchronous call operation drives the business processing function to be re-executed with the current state variable when the life cycle of the callback data object ends. After the response to the asynchronous call operation is returned, the response data is processed according to the current state variables. After all the response data of the asynchronous call operations has been processed, the response content of the business request is constructed and sent.

2. The method according to claim 1, characterized in that, The process of creating a reactor thread and initializing thread-local resources upon framework startup includes: When the framework starts, a reactor thread is created and the event scheduler in the thread-local resources is initialized; The event scheduler establishes network and database connections, and registers the network and database connection information with the event scheduler for periodic monitoring. Register the server listening port to the event scheduler, initialize the command identifier numberer, and start the event listening loop to listen for business requests.

3. The method according to claim 1, characterized in that, The context information includes client request context information and third-party service request context information; therefore, in response to a detected business request, the creation of a request object for the business request based on a unified framework request base class includes: In response to a detected business request, the business type is determined based on the feature information carried in the business request, and a request object corresponding to the business type is created based on a unified framework request base class. The client request context information is extracted from the business request, and the third-party service request context information and state variables corresponding to the business type are initialized. The state variables include an initial state, at least one response waiting state, and a completion state. Invoke the business processing function of the request object, and execute the business process in the business processing function according to the current state variable.

4. The method according to claim 3, characterized in that, The process of executing the business flow in the business processing function of the request object, and switching the state variable according to the context information and calling the asynchronous command sending function when the business flow reaches the IO call operation, includes: In the business processing function of the request object, the business process corresponding to the initial state is executed; Repeat the following steps: After the business process reaches the IO call operation and the previous state of the business process is completed, the state variable is set to the next state according to the context information, and the asynchronous command sending function is called. At least one I / O command is sent through the asynchronous command sending function and returned immediately, wherein each I / O command corresponds to a command identifier, and the command identifier is maintained in the thread-local resource.

5. The method according to claim 1, characterized in that, The step of creating a callback data object and constructing an asynchronous operation object through the asynchronous command sending function, and then executing the asynchronous call operation through the asynchronous operation object, includes: Within the asynchronous command sending function, the command template and parameters passed by the business processing function are received, and the command template and parameters are combined to generate a command string; Obtain the command identifier from the thread-local resource and create a callback data object, wherein the callback data object stores the command identifier and the address pointer of the request object; Define a callback function, and associate the callback data object as a parameter with the callback function, wherein the callback function is executed automatically when the response of the asynchronous call operation arrives; The connection channel information registered in the thread-local resources, the command string, the callback function, and the callback data object are combined to construct the asynchronous operation object; The asynchronous operation object is used to perform an asynchronous call operation, and the obtained command identifier is returned to the business processing function.

6. The method according to claim 1, characterized in that, The step of processing the response data according to the current state variables after the asynchronous call operation returns includes: When the response to the asynchronous call operation is returned, the business processing function of the request object is re-executed, and the user jumps to the corresponding processing logic block in the business processing function according to the current state variable; Within the processing logic block, the command identifier corresponding to the currently returned response is obtained, and the corresponding response data is extracted from the response storage area of ​​the request object based on the command identifier. The corresponding asynchronous call operation is determined based on the command identifier, and the business process related to the command identifier within the processing logic block is executed to process the response data.

7. The method according to claim 1, characterized in that, After all asynchronous call operation response data processing is completed, constructing and sending the response content of the business request includes: After the current response data has been processed, check the response status of all asynchronous call operations that the business request depends on, based on the sent command identifier and the processed command identifier. If there is an unreturned or unprocessed response, the current state variable remains unchanged, the business processing function finishes execution and returns, and continues to wait for subsequent responses; If it is confirmed that the responses to all asynchronous call operations have been returned and processed, the response content of the business request is generated by combining all the processed response data. The framework calls the response sending method to return the response content to the client corresponding to the business request, and destroys the request object of the business request after the response content is sent.

8. An asynchronous I / O call device for business code, the device being used to complete an asynchronous call process within a single reactor thread, characterized in that, The device includes: The resource initialization module is used to create a reactor thread and initialize thread-local resources when the framework starts. The thread-local resources include an event scheduler for listening to business requests. The request object creation module is used to respond to a listened business request by creating a request object for the business request based on a unified framework request base class. The request object contains the context information and state variables of the business request. The business process execution module is used to execute the business process in the business processing function of the request object, and when the business process reaches the IO call operation, switch the state variable according to the context information and call the asynchronous command sending function; The asynchronous I / O call module is used to create a callback data object and construct an asynchronous operation object through the asynchronous command sending function, and to execute asynchronous call operations through the asynchronous operation object. The response data processing module is used to process the response data according to the current state variables after the response of the asynchronous call operation is returned, and to construct and send the response content of the business request after all the response data of the call operation has been processed.

9. A storage medium having a computer program stored thereon, characterized in that, When the computer program is executed by a processor, it implements the method of any one of claims 1 to 7.

10. A computer device, comprising a storage medium, a processor, and a computer program stored on the storage medium and executable on the processor, characterized in that, When the processor executes the computer program, it implements the method of any one of claims 1 to 7.

Citation Information

Patent Citations

  • Single-thread resource scheduling method and device, equipment and storage medium

    CN114510336A

  • Asynchronous request processing method and device and electronic equipment

    CN118869818A