It is generally intuitive for a code developer to develop a sequential task that, when executes, operates from task start to task end. However, such sequential tasks are inefficient to execute as they maintain system resources unnecessarily, e.g., they maintain processing threads and system memory even when they are simply waiting for another, e.g., time consuming, operation to be performed.
Asynchronously executing tasks resolve this system resource concern by having system resources released when the task cannot continue processing until another, e.g., time consuming, operation is first performed. In this manner, processing threads and system memory can be utilized by other tasks and task instances, i.e., task concurrencies, during the time a task cannot process until another operation to be performed is finalized.
Asynchronous task development, maintenance and modification can, however, be difficult, if not nearly impossible, to perform as traditional asynchronously executing tasks must be developed into two parts with callbacks explicitly designed therein to manage the asynchronous execution handling and proper task processing resumption. With any complexity within the asynchronously developed task the asynchronous execution flow management code development, maintenance and modification can present very difficult challenges for code developers, which translates into a variety of unwelcome costs for the company developing the code.
As an example, it is a common pattern for companies to design a multi-tier application/service for production/request work item processing wherein a front end accepts the requests while a backend processes the requests, and, e.g., returns a result(s). This can be seen in many consumer-producer models where consumer task instances, or concurrencies, consume items that producer task instances produce.
Developed as sequential task logic these models are intuitively straightforward to generate logic for, and thereafter maintain and modify. However, such sequential task logic can effect inefficient utilization of system resources and can often result, during execution, in processing thread blockage and ultimately task user dissatisfaction.
Alternatively, developed as asynchronous task logic these models generally efficiently utilize system resources and minimize, and can even eliminate, processing thread blockage. However, such asynchronous task logic can easily and quickly become cost prohibitive to develop and/or maintain and/or modify.
Thus, it is desirable to provide a generic asynchronous logic flow solution that combines the relative ease of sequential task code development, including code generation, maintenance and modification, with the efficient system resource utilization of asynchronous task code execution. It is desirable to provide code developers with an effective sequential fashion asynchrony interface to hold software logic directly. It is desirable to enable code developers to set and/or reset the concurrency of an execution flow at runtime with ease. It is desirable to enable code developers to efficiently sync up with or chain different execution flows with differing concurrencies without running the risk of processing thread blockage. It is desirable to allow developers to start execution flows in any order without having to account for execution flow dependencies.
This summary is provided to introduce a selection of concepts in a simplified form which are further described below in the Detailed Description. This summary is not intended to identify key or essential features of the claimed subject matter, nor is it intended to be used as an aid in determining the scope of the claimed subject matter.
Embodiments discussed herein include methodology for developing tasks with sequential code logic and thereafter managing an asynchronous execution of the tasks during time consuming operation execution flow.
In embodiments tasks are developed with sequential logic and are associated with at least one callback wrapper which can manage an asynchronous execution of a task instance when the task has invoked the execution of a time consuming operation. In embodiments the callback wrapper manages the temporary suspension of a task instance execution when the task instance has invoked a time consuming operation. In embodiments the callback wrapper manages the execution of the invoked time consuming operation and thereafter executes a callback to the particular task instance invoking the time consuming operation. In embodiments the task instance can thereafter resume sequential logic processing of its code.
In embodiments tasks can be defined with one or more concurrencies. In embodiments task thread usage can be managed on the fly by a modification of the task defined concurrency at a runtime.
These and other features will now be described with reference to the drawings of certain embodiments and examples which are intended to illustrate and not to limit, and in which:
In the following description, for purposes of explanation, numerous specific details are set forth in order to provide a thorough understanding of embodiments described herein. It will be apparent however to one skilled in the art that the embodiments may be practiced without these specific details. In other instances well-known structures and devices are either simply referenced or shown in block diagram form in order to avoid unnecessary obscuration. Any and all titles used throughout are for ease of explanation only and are not for any limiting use.
At task end 115 the thread 130 for a sequential task 110 is released and the sequential task 110 is removed from, or otherwise is no longer referenced in, system memory 150. In some embodiments the released thread 130 is returned to a thread pool 140 and can thereafter be utilized by other tasks desiring to execute.
In known sequential tasks 110, because they are executed from task start 105 to task end 115, any time consuming operation 190 performed in a task block 120, e.g., an I/O (input/output) call, a web service request, a time consuming computation, etc., renders the sequential task 110 execution relatively inefficient. This is because, e.g., the sequential task 110 continues to utilize system 100 resources, e.g., continues to inhabit system memory 150 and continues to utilize its associated thread 130 while waiting for the time consuming operation 190 to complete or otherwise end, to the potential detriment of other system task execution. Sequential tasks 110 may go to sleep during a time consuming operation 190 execution but they continue to utilize system resources, e.g., occupy system memory 150 and utilize a thread 130, and are therefore inefficient in this manner.
Thus, while sequential tasks 110 are generally easier to understand, debug and maintain than asynchronous tasks 160, also shown in
As noted,
In known systems 100 an asynchronous task code block 120 that initiates a time consuming operation 190 is divided into two sub-blocks 125 and 135. A first task code sub-block 125 executes the asynchronous task code block 120 from code block start 145, which if it is the first code block 120 of the asynchronous task 160 will also be task start 105, until the time consuming operation 190 is called, or otherwise initiated, 155. A second task code sub-block 135, also referred to herein as a callback sub-block 135, thereafter executes the asynchronous task code block 120 from when the asynchronous task 160 is subsequently reconstituted in system memory 150, as further described below, until the asynchronous task code block end 165 or another time consuming operation 190 is initiated within the task code block 120.
In at least some known systems 100 the asynchronous task 160 utilizes a callback operation 170, also referred to herein as simply a callback 170, to resume proper execution when the time consuming operation 190 is completed, or otherwise ended. In at least some known systems 100 the callback 170 executes to obtain a thread 130, e.g., from the thread pool 140, for the asynchronous task 160 and the asynchronous task 160 is reconstituted in system memory 150 so it can thereafter properly resume execution where it left off when it made the time consuming operation 190 request, now at the start of the second, callback, sub-block 135. In embodiments the newly acquired thread 130 can be the same thread 130 that was previously assigned, or otherwise attached, to the asynchronous task 160 or it can be a new, different, thread 130.
At asynchronous task end 115 the thread 130 the asynchronous task 160 is then associated with is released and the asynchronous task 160 is removed from, or otherwise is no longer referenced in, system memory 150. In some embodiments the released thread 130 is returned to a thread pool 140 and can thereafter be utilized by other tasks desiring to execute.
While the discussion with regard to
In an embodiment the alf system 200 supports coordination and synchronization between different task 210 flows, i.e., between the processing of various tasks 210. For a complex application it is generally not effective or efficient for a developer(s) to attempt to write the entire logic, i.e., code, in a single task 210. Different tasks 210 can be generated for accomplishing different activities, e.g., some tasks 210 flows generate inputs to other tasks 210, some tasks 210 flows accept inputs from other tasks 210, some tasks 210 flows require a condition to be fulfilled by another task 210 flow in order to continue, some tasks 210 flows notify other tasks 210 to certain events, etc. In an embodiment multiple task 210 flow design assists in decoupling the components of a complex application. In an embodiment various tasks 210 of the alf system 200 can be assigned differing concurrencies, as further discussed below, and the task concurrencies, also referred to as task instances, can each run, i.e., execute, asynchronously although the tasks 210 themselves are created with a sequential code design.
In an embodiment alf system 200 tasks 210 are lock free. In an embodiment alf system 200 tasks 210 are loosely coupled, and consequently, their execution start order is immaterial to overall proper alf system 200 functionality, as further described below. In an embodiment alf system 200 tasks 210 and task instances are robust.
In an embodiment alf system 200 the code 220 for tasks 210 can be developed, or otherwise formatted, sequentially even though the tasks 210 will execute asynchronously during an invoked time consuming operation 190 execution. In an embodiment the asynchronous execution of a task 210 is accomplished with internal callbacks that are transparent to the task code 220 developers, as further described below. Thus, in this embodiment developers need not create separate sub-blocks, e.g., sub-blocks 125 and 135, for a task code block 220 that executes time consuming operations 190 where asynchronous execution flow is employed.
As noted, an embodiment alf system 200 can have one or more tasks 210. And as noted, in an embodiment tasks 210 can consist of one or more task code blocks 220, also referred to herein simply as code 220.
In an embodiment time consuming activities, or tasks, 190 are defined as operations 230; e.g., in an embodiment a code developer defines some time consuming task 190, e.g., an I/O call, a web service request, etc., or a combination of two or more time consuming tasks 190, or a combination of a time consuming task 190 and other functionality, as an operation 230. For example, in an embodiment a developer can define an operation, e.g., task1, that is the time consuming task 190 of enqueuing an item, i.e., storing an item in a queue. As another example, in an embodiment a developer can define an operation, e.g., task2, to be the time consuming task 190 of dequeuing an item, i.e., retrieving an item stored in a queue.
For purposes of simplicity of discussion time consuming tasks 190 and their respective time consuming operations 230 are used interchangeably herein and thus, reference to a time consuming task 190 can properly be a reference to a time consuming operation 230 and vice versa.
In embodiments a time consuming task 190, or operation 230, can be any functionality that is invoked by a task 210 that requires processing by some entity, e.g., task, application, etc., other than the task 210 itself. Thus, in embodiments a time consuming task 190 may not actually be time consuming in any real measurable sense but may require the usage of limited resources that are not always immediately available when the task 210 first invokes execution of the time consuming operation 190.
In an embodiment a return call 240 is included into the task code block 220 at the point where task 210 execution is to resume subsequent to a time consuming operation 190 execution. In an aspect of this embodiment the return call 240 is a “yield return” call that is understandable by and can be properly processed by the known .net system. For example, a “yield return task1” call is included into a task code block 220 when the task code block 220 is to initiate the performance of the task1 time consuming task of enqueuing an object onto a queue. As another example, a “yield return task2” call is included into a task code block 220 when the task code block 220 is to initiate the performance of the task2 time consuming task of dequeuing an object from a queue.
In other aspects of this embodiment the return call 240 can be other return calls that are understandable to and can be properly managed by other existing systems.
In an embodiment when a task code block 220 initiates a time consuming operation 190 control is given to a callback wrapper 250, also referred to herein as a callback operation 250. In an embodiment the callback wrapper 250 is code that transparently manages asynchronous execution of the task 210 during the time consuming operation 190 execution. In an embodiment the callback wrapper 250 effectively manages a callback 270 to the task code block 220 at the proper location, i.e., the return call 240, for continuing task 210 execution.
In an embodiment the callback wrapper 250 manages the release 225 of the thread 130 for a task 210 when a time consuming operation 190 has been initiated. In an aspect of this embodiment the callback wrapper 250 manages the release 225 of the thread 130 to a thread pool 140 when a time consuming operation 190 has been initiated by a task 210.
In an embodiment the task 210 is thereafter removed from, or otherwise disassociated with, system memory 150, and thus memory 150 becomes available for another task 210's usage.
In an embodiment a task code block 220 calls, or otherwise initiates, the execution of a time consuming task 190 by including the defined operation 230 for the time consuming task 190 in a return call. In an embodiment the callback wrapper 250 thereafter takes over management of the initiation 245 of the time consuming operation 190 identified via the operation 230 included in a task's return call 240.
In an embodiment the callback wrapper 250 manages the completion, or termination, 275 of the time consuming task 190 in the sense that the callback wrapper 250 handles a callback 270 that the callback wrapper 250 establishes to the task 210. Thus, in an embodiment the callback 270 to the task code block 220 is transparent to the task code block 220 and thus the task code block 220 can be developed with a sequential design.
As noted, in an embodiment the callback wrapper 250 generates the callback 270 to the task 210 that results in a thread 130 being once more associated 235 with the task 210 and the task 210 being repopulated in memory 150 for continuing processing.
In an embodiment the task 210 can thereafter resume execution. In an embodiment, while the time consuming operation 190 is being performed, i.e., is executing, at the behest of a task 210 the task 210 has no thread 130 associated with it and the task 210 is not associated with memory 150, and thus, behaves asynchronously. In an embodiment the task 210 however does not have to manage its callback from the time consuming operation 190, and thus does not have to have the respective code block 220 developed into two sub-blocks, e.g., sub-block 125 and sub-block 135 as discussed with reference to
In an embodiment a “move next ( )” operation known to the .net system is utilized to manage the callback 270 generated by the callback wrapper 250 to the proper task code block 220. In an embodiment the callback wrapper 250 ensures that any result(s) produced from the time consuming task 190 execution is(are) returned to, or otherwise provided to, the task code block 220.
In an embodiment the .net system has an enumerator methodology that has the capability to maintain a list of things, which can theoretically be any things capable of being listed. In an embodiment the enumerator methodology of the .net system is utilized by the alf system 200 to maintain track of task code blocks 220 as they release threads 130 and become disassociated with memory 150 during asynchronous flow activity and thereafter acquire threads 130 and become repopulated in memory 150 to resume execution.
In an embodiment alf system 200 the introduction of the callback wrapper 250 assists in decoupling tasks 210 and task instances and in connecting task components, e.g., task code blocks 220, naturally and efficiently. In an embodiment the callback wrapper 250 provides, i.e., establishes, a callback 270 for a task code block 220, ensures the execution of a requested time consuming operation 190 and asynchronously waits on, e.g., yield, the time consuming operation 190 to be completed, or otherwise terminated. In an embodiment when a time consuming operation 190 execution is ended the callback wrapper 250 control completes with any result returned from the time consuming operation 190 properly provided to the task 210 at the task code 220 execution point where the task code 220 instigated the time consuming operation 190.
In an embodiment the caller of the callback operation 250, i.e., the task code block 220, is awakened by a thread 130, e.g., obtained from a thread pool 140, with any result returned from the time consuming operation 190, and the task code block 220 thereafter continues its execution.
In an embodiment tasks 210 are derived from a class that defines the respective task code 220 as asynchronous. In an aspect of this embodiment tasks 210 are derived from an AsyncFlow class that defines the task code 220 as asynchronous.
Referring to
In an embodiment a task 210 with multiple concurrencies 260 defined by developer(s) can execute freely and asynchronously on logically different contexts without the issue of thread 130 blocking. In an embodiment the number of task concurrencies 260 does not require the same number of threads 130. In an embodiment even one thread 130 can effectively support a number of multiple task concurrencies 260 in the alf system 200. In an embodiment alf system 200 as a thread 130 will be released when a task 210 has initiated a time consuming operation 190 the released thread 130 can thereafter be reassigned to another task concurrency 260 and overall task concurrency flow, i.e., execution will remain uninterrupted.
In an embodiment the concurrency 260 of a task 210, i.e., the number of task 210 instances 260 that can execute concurrently, can be altered at runtime. In an embodiment the concurrency 260 of a task 210 can be changed during task execution with a concurrency change operation. In an aspect of this embodiment the concurrency 260 of a task 210 can be changed at runtime utilizing the call “AsyncFlow.SetConcurrency(int concurrency)” to initiate a set task concurrency operation wherein the parameter “int concurrency” is an integer identifying the number of concurrencies 260 to establish for the task 210.
In an embodiment increasing the concurrency 260 of a task 210 results in additional concurrency tickets 280 being posted, i.e., generated and utilized by the alf system 200, for execution of the respective task 210 instances 260 associated with the concurrency tickets 280. In an embodiment decreasing the concurrency 260 of a task 210 results in the removal, or deletion, or Muse, of posted concurrency tickets 280 for those task instances 260 that will no longer be executed with the change in task concurrency 260.
In an embodiment concurrency tickets 280 are used by the alf system 200 to identify the instance 260, also referred to herein as task concurrency 260, concurrency 260 and logical sub-flow 260, of a task 210 that is executing. In an embodiment if a task 210 has multiple concurrencies 260 then the different logical sub-flows 260 of the task 210 will each be assigned a unique concurrency ticket identification 285. In an embodiment a logical sub-flow's concurrency ticket identification 285 assists the alf system 200 to identify each logical sub-flow 260 that is executing to properly manage the logical sub-flow 260 through both its sequential and asynchronous processing.
In an embodiment for a task 210 with n concurrencies 260 there will be n concurrency tickets 280, one of each that is provided to, or otherwise associated with, each different logical sub-flow 260. In an embodiment logical sub-flows 260 of a task 210 are assigned sequential numerical concurrency ticket identifications 285. In an aspect of this embodiment a first logical sub-flow 260 of a task 210 is assigned a concurrency ticket identification 285 of zero (0), a second logical sub-flow 260 of a task 210 is assigned a concurrency ticket identification 285 of one (1), etc., with the last concurrency 260 of n concurrencies 260 of a task 210 being assigned a concurrency ticket identification 285 of n minus one (n−1).
In other embodiments and aspects logical sub-flows 260 of a task 210 are assigned other concurrency ticket identifications 285, e.g., alphabetic concurrency ticket identifications, i.e., A, B, C, etc., decreasing sequential numerical ticket identifications, random numerical ticket identifications, etc.
In an embodiment when a concurrency ticket identification 285 is assigned to a certain logical sub-flow 260 of a task 210 on a first run, i.e., first execution, of the sub-flow 260, with subsequent runs, i.e., executions, of the same logical sub-flow 260, the logical sub-flow 260 retains the same assigned concurrency ticket identification 285.
In an embodiment concurrency ticket identifications 285 are similar to thread identifications provided by the operating system (OS) but come with a predictable range when they are assigned as sequentially numerical identifications.
In an embodiment concurrency tickets 280 and concurrency ticket identifications 285 allow for the identification as well as unique handling and unique processing of particular logical sub-flows 260 of a task 210. In an aspect of this embodiment concurrency tickets 280 and concurrency ticket identifications 285 can be utilized within the alf system 200 to assign a limited number of identified logical sub-flows 260 the execution of specific functionality, also referred to herein as limited task instance functionality 215. For example, in an embodiment with a task 210 with one-hundred (100) concurrencies 260 a logical sub-flow 260 with a concurrency ticket identification 285 of one (1) and a logical sub-flow 260 with a concurrency ticket identification 285 of three (3) can be assigned to execute a limited task instance functionality 215 of indexing that the other logical sub-flows 260 are not to do. Thus, referring to
Referring again to
In an embodiment the start task 255 internally posts, or otherwise generates and thereafter manages, a proper number of concurrency tickets 280 for task 210 execution management. In an embodiment the proper number of concurrency tickets 280 is determined by the concurrency setting of the task 210 at the time the start task 255 is invoked for the task 210. In an embodiment each posted concurrency ticket 280 causes the alf system 200 to create a new logical sub-flow 260 of the task 210 and initiate the logical sub-flow's execution.
As an example, and referring to
In
In an embodiment after the start call 255 is executed for a task 210 all the concurrent logical sub-flows 260 generated and executed for the task 210 are free-running.
Referring again to
In an embodiment at the beginning of the execution of a logical sub-flow 260 of a task 210 an execution allowance check is made to ascertain whether execution flow for the task instance 260 is in a terminated state. Execution flow can be in a terminated state for a variety of reasons, including but not limited to, the machine the alf system 200 is operating on is shutting down.
In an embodiment at the beginning of the execution of a logical sub-flow 260 of a task 210 a second execution allowance check is made to ascertain whether the task's concurrency 260 allows for the logical sub-flow 260 to execute. In an embodiment a logical sub-flow 260 may not be allowed to execute as the concurrency of its task 210 can be altered during runtime with the potential to result in the logical sub-flow 260 no longer being wanted, etc.
In an embodiment after passing these execution allowance checks an iterator 290 related to the concurrency ticket 280 created for the logical sub-flow 260 is created by the alf system 200 to enumerate the logical sub-flow 260 in order for the alf system 200 to manage its logic sub-flow execution. In an embodiment the task instance 260 then executes as programmed.
An iterator 290, also referred to herein as an enumerator 290, can be thought of as a type of pointer that references one particular element in an element collection at a time, referred to as element access, and modifies itself so that it then points, or otherwise references, the next element in the element collection, also referred to as element traversal. A primary purpose of an iterator 290 in the alf system 200 is to allow the alf system 200 to process every element, i.e., every logical sub-flow 260, while not requiring the tasks 210, and the task developers, to be concerned with how the existing logical sub-flows 260 are particularly identified during their execution.
Within the known .net framework iterators 290, i.e., enumerators 290, are represented by the IEnumerator interface. IEnumerator provides a MoveNext( )method which advances the enumerator 290 to the next element, i.e., in this instance the next logical sub-flow 260, and indicates whether the end of the collection of elements has been reached. In an embodiment enumerators 290 are typically obtained by invoking a GetEnumerator( ) method.
Referring again to
As can be seen the exemplary logic code 625 utilizes the IEnumerator interface 627 which will provide the MoveNext( ) methodology for properly, and transparently, managing the task instances 260.
In logic code 625 the ExecuteFlow( ) call is the execute flow call 620 to launch the execution of the logical sub-flows 260 of a task 210.
In an embodiment, before creating an iterator 290 for task 210 execution, a state check is made to determine if task 210 termination is required, e.g., because the machine the task 210 is executing upon is shutting down. If termination is required the alf system 200 initiates a task 210 termination processing.
In an embodiment when task 210 execution is to be terminated the alf system 200 waits for all the concurrencies 260 of a task 210 to quit the execution loop, i.e., for each to stop executing, before the alf system 200 terminates task 210 execution, e.g., when the machine the alf system 200 is operating upon is shutting down. In an embodiment this termination protocol assists in preventing requests and/or work items from unexpected, and potentially unknown state, termination.
In an embodiment a task 210 can customize its termination processing and/or the termination processing for one or more of its logical sub-flows 260 by overriding the default alf system 200 task termination processing. Referring to
In the above exemplary logic code the OnTermination( ) call is the task termination call to cause the alf system 200 to execute the included customized termination processing code when the alf system 200 is to terminate task 210, or one or more task logic sub-flow 260, execution.
In an embodiment the alf system 200 termination process is also a form of sequential asynchrony. In an embodiment this can be useful when a task 210 is performing some complex I/O intensive termination processing, e.g., signing out from a remote service.
In an embodiment termination override can also be used by a task 210 when decreasing its concurrency 260, e.g., via SetConcurrency(int numberofConcurrency) where numberofConcurrency is less than the number of currently existing task instances 260.
A scenario in which the alf system 200 can be effectively utilized is a producer-consumer problem as depicted in
In an embodiment producer-consumer scenario the producer's storing 312 of an item 315 in the queue 330 is a time consuming task 190 and the consumer's retrieval 314 of an item 315 from the queue 330 is also a time consuming task 190.
Utilizing the pseudo logic code 350 of
As can be seen in the pseudo logic code 350 both the exemplary producer task 360 and the exemplary consumer task 380 accomplish the execution of allowance checks, the creation of the enumerator 290 for their respective logical sub-flows 260 and the launch of the execution of each instance 260 of their task 210 utilizing the IEnumerator interface and the ExecuteFlow( ) call as seen in the respective code lines 361 and 381.
In the exemplary producer task 360 a first stage 372, or part, is accomplished before the “yield return” invocation 370 at code line 367 when the time consuming task 190 of enqueuing an item 315 to the shared queue 330 is asynchronously executed. As can be seen at code line 364 a ProduceItem( ) call 363 is performed to generate and return an Item 362 to the ProducerFlow task 360.
At code line 365 an enqueue operation, enqueueOperation, 366, i.e., an operation for storing 312 an item 315, i.e., an Item 362 produced by the ProduceItem( ) call 363, to the shared queue 330, is created.
At code line 367 a yield return 370 is invoked for the defined enqueueOperation 366 which causes the ProducerFlow task 360 to execute asynchronously with a transparent callback 270 managed by the alf system 200. In this way, when the enqueueOperation 366 is invoked to enqueue a produced Item 362 on the shared queue 330 the currently executing logical sub-flow 260 of the ProducerFlow task 360 will relinquish its processing thread 130 and be deleted from, or otherwise disassociated with, memory 150 and for executing purposes cease to exist.
The logical sub-flow 260 of the ProducerFlow task 360 will thereafter be reconstituted, or otherwise repopulated, in memory 150 and a thread 130 assigned to it for processing resumption at the yield return 370 when the enqueuing processing is completed, or otherwise terminated.
At this point, a second state 374, or part, of the exemplary producer task 360 can execute with any additional producer task 360 processing. However, as is illustrated in the pseudo code 350, in an embodiment this second stage 374 of the exemplary producer task 360 is sequential to the first stage 372 even though it is subsequently executed asynchronously by the alf system 200.
In the exemplary consumer task 380 a first stage 387, or part, is accomplished before the “yield return” invocation 386 at code line 385 when the time consuming task 190 of dequeuing an item 315 from the shared queue 330 is asynchronously executed.
At code line 383 a dequeue operation, dequeueOperation, 382, i.e., an operation for retrieving 314 an item 315, i.e., an Item 362 produced by the ProduceItem( ) call 363, from the shared queue 330, is created. The exemplary dequeueOperation 382 returns a WorkItem 384 which is the item 315 retrieved 314 from the shared queue 330 during the dequeueOperation 382 processing.
At code line 385 a yield return 386 is invoked for the defined dequeueOperation 382 which causes the ConsumerFlow task 380 to execute asynchronously with a transparent callback 270 managed by the alf system 200. In this way, when the dequeueOperation 382 is invoked to dequeue a WorkItem 384 from the shared queue 330 the currently executing logical sub-flow 260 of the ConsumerFlow task 380 will relinquish its processing thread 130 and be deleted from, or otherwise disassociated with, memory 150 and for executing purposes cease to exist.
The logical sub-flow 260 of the ConsumerFlow task 380 will thereafter be reconstituted, or otherwise repopulated, in memory 150 and a thread 130 assigned to it for processing resumption at the yield return 386 when the dequeue processing is completed, or otherwise terminated.
At this point, a second state 389, or part, of the exemplary consumer task 380 can execute to process the item 315 retrieved 314 from the shared queue 330. Exemplary code line 391 assigns the result of the dequeueOperation 382 processing, i.e., the retrieved item 315, to workitem 392. Thereafter an exemplary ProcessItem( ) call is made 393 to process the retrieved workitem 392. In an embodiment this second stage 389 of the exemplary ConsumerFlow task 380 is sequential to the first stage 387 even though it is subsequently executed asynchronously by the alf system 200.
In the producer-consumer model of
For the scenario where there is room to enqueue 312 a newly produced item 315 in the example and an embodiment the time when the ProducerFlow task 360 instance 260 ceases to exist for enqueuing operation 366 processing is the time needed to relinquish the task instance 260 processing thread 130, enqueue 312 the produced item 315 and thereafter re-establish the task instance 260 in memory 150 and assign a processing thread 130 to it. For the scenario where there is no room to enqueue 312 a newly produced item 315 in the example and an embodiment the time when the ProducerFlow task 360 instance 260 ceases to exist for enqueuing operation 366 processing is the time needed to relinquish the task instance 260 processing thread 130, plus the time it takes for the shared queue 330 to have at least one item 315 dequeued from it so that it once again has space for enqueuing 312 an item 315, plus the time for enqueuing 312 a newly produced item 315, and thereafter, the time required to re-establish the task instance 260 in memory 150 and again assign a processing thread 130 to it.
In the example and an embodiment, when the dequeue operation 382 is executed, i.e., yielded, thread processing for the ConsumerFlow task 380 instance 260 will seamlessly continue on when there is an item 315 in the shared queue 330 to be dequeued, i.e., retrieved, 314. Otherwise, via the (Enumerator of exemplary code line 381, in the example and an embodiment the ConsumerFlow task 380 instance 260 will cease to executably exist, i.e., it will have relinquished its processing thread 130 and it will not be associated within memory 150, until an item 315 is subsequently available in the shared queue 330 for retrieval 314. In an embodiment in both these scenarios the ConsumerFlow task 380 instance 260 ceases to executably exist during the time consuming dequeue operation 382.
For the scenario where there is an item 315 currently available to be dequeued 314 from the shared queue 330 in the example and an embodiment the time when the ConsumerFlow task 380 instance 260 ceases to exist for dequeuing operation 382 processing is the time needed to relinquish the task instance 260 processing thread 130, dequeue 314 an item 315 from the shared queue 330 and thereafter re-establish the task instance 260 in memory 150 and assign a processing thread 130 to it. For the scenario where there is no item 315 currently stored in the shared queue 330 in the example and an embodiment the time when the ConsumerFlow task 380 instance 260 ceases to exist for dequeuing operation 382 processing is the time needed to relinquish the task instance 260 processing thread 130, plus the time it takes for a ProducerFlow 360 instance 260 to generate and enqueue 312 at least one item 315 to the shared queue 330, plus the time for dequeuing 314 an item 315, and thereafter, the time required to re-establish the consumer task 380 instance 260 in memory 150 and assign a processing thread 130 to it.
In an embodiment and referring to
For illustrative purposes the callback wrapper 400 of
In an embodiment the callback wrapper 400, also referred to herein as the shared queue callback wrapper 400, internally maintains one item queue 410 and two callback queues 420 and 430. In an embodiment and the example one callback queue 420, e.g., the Producer callback queue 420, is for managing ProducerFlow task 360 processing. In an embodiment and the example the other callback queue 430, e.g., the Consumer callback queue 430, is for managing ConsumerFlow task 380 processing.
In an embodiment and the example when an instance 260 of the ProducerFlow task 360 has produced an item 315 the instance 260 is queued to the Producer callback queue 420 by the callback wrapper 400 when there is no room in the item queue 410 to store the produced item 315. In an alternative embodiment and the example, when an instance 260 of the ProducerFlow task 360 produces an item 315 the instance 260 is queued to the Producer callback queue 420 by the callback wrapper 400. In both of these embodiments the queued instance 260 of the ProducerFlow task 360 is dequeued by the callback wrapper 400 when there is space in the item queue 410 to store the ProducerFlow task instance's produced item 315 and the item 315 is queued 312.
In an embodiment and the example when an instance 260 of the ConsumerFlow task 380 invokes the dequeue operation 382 to retrieve 314 an item 315 from the shared, item, queue 410, the instance 260 is queued to the Consumer callback queue 430 by the callback wrapper 400 when there is no item 315 currently stored in the item queue 410. In an alternative embodiment and the example, when an instance 260 of the ConsumerFlow task 380 invokes the dequeue operation 382 to retrieve 314 an item 315 from the shared item queue 410 the instance 260 is queued to the Consumer callback queue 430 by the callback wrapper 400. In both of these embodiments the queued instance 260 of the ConsumerFlow task 380 is dequeued by the callback wrapper 400 when there is an item 315 in the item queue 410 available to be dequeued 314 and the item 315 is dequeued 314.
In an embodiment and the example, when the dequeue operation 382 is invoked from a ConsumerFlow task 380 instance 260 the shared queue callback wrapper 400 checks to see if there are any items 315 available in the item queue 410 for retrieval. If there are the dequeue operation 382 is executed to retrieve an item 315 from the item queue 410 and thereafter the shared queue callback wrapper 400 invokes the requesting ConsumerFlow task 380 instance 260 with the retrieved item 315. Because space has now become available in the item queue 410 in an embodiment and the example the shared queue callback wrapper 400 checks to see if there is a ProducerFlow task 360 instance 260 queued in the Producer callback queue 420. If yes, the shared queue callback wrapper 400 dequeues a ProducerFlow task 360 instance 260 from the Producer callback queue 420, enqueues 312 the respective item 315 produced by the dequeued ProducerFlow task 360 instance 260 to the item queue 410, and thereafter invokes the ProducerFlow task 360 instance 260 to resume execution at the established yield return 370 invocation, e.g., code line 367 of the exemplary ProducerFlow task 360 of
When an item 315 is enqueued 312 in the item queue 410 in an embodiment and the example the shared queue callback wrapper 400 checks to see if there is a ConsumerFlow task 380 instance 260 queued in the Consumer callback queue 430. If yes, the shared queue callback wrapper 400 dequeues a ConsumerFlow task 380 instance 260 from the Consumer callback queue 430, dequeues 314 an item 315 from the item queue 410, and thereafter invokes the ConsumerFlow task 380 instance 260 with the retrieved item 315 to resume execution at the established yield return 386 invocation, e.g., code line 385 of the exemplary ConsumerFlow task 380 of
In an embodiment and the example, the shared queue callback wrapper 400 continues processing between the ProcessingFlow task 360 and the ConsumerFlow task 380.
In an embodiment and the example, when the dequeue operation 382 is invoked from a ConsumerFlow task 380 instance 260 and the shared queue callback wrapper 400 checks to see if there are any items 315 available in the item queue 410 for retrieval, if there are not the shared queue callback wrapper 400 queues the ConsumerFlow task 380 instance 260 to the Consumer callback queue 430. In an aspect of this embodiment and example the shared queue callback wrapper 400 queues a reference to the ConsumerFlow task 380 instance 260 that cannot continue processing until there is an item 315 in the item queue 410 to retrieve 314. In an aspect of this embodiment and example the shared queue callback wrapper 400 queues the concurrency ticket 280 for the ConsumerFlow task 380 instance 260 that cannot continue processing until there is an item 315 in the item queue 410 to retrieve 314.
In an embodiment and the example when the enqueue operation 366 is invoked from a ProducerFlow task 360 instance 260 the shared queue callback wrapper 400 checks to see if there is any room in the item queue 410 to store the produced item 315. If there is the enqueue operation 366 is executed to store the item 315 produced by the ProducerFlow task 360 instance 260 in the item queue 410 and thereafter the shared queue callback wrapper 400 invokes the requesting ProducerFlow task 360 instance 260 to continue its processing at the yield return 370 invocation, e.g., exemplary code line 367 of the exemplary ProducerFlow task 360 of
When an item 315 is dequeued 314 from the item queue 410 in an embodiment and the example the shared queue callback wrapper 400 checks to see if there is a ProducerFlow task 360 instance 260 queued in the Producer callback queue 420. If yes, the shared queue callback wrapper 400 dequeues a ProducerFlow task 360 instance 260 from the Producer callback queue 430, enqueues 312 the respective produced item 315 to the item queue 410, and thereafter invokes the ProducerFlow task 380 instance 260 to resume execution at the established yield return 370 invocation, e.g., exemplary code line 367 of the exemplary ProducerFlow task 360 of
In an embodiment and the example the shared queue callback wrapper 400 continues processing between the ProducerFlow task 360 and the ConsumerFlow task 380.
In an embodiment and the example when the enqueue operation 366 is invoked from a ProducerFlow task 360 instance 260 and the shared queue callback wrapper 400 checks to see if there is room in the item queue 410 to store the produced item 315, if there is not the shared queue callback wrapper 400 queues the ProducerFlow task 360 instance 260 to the Producer callback queue 420. In an aspect of this embodiment and example the shared queue callback wrapper 400 queues a reference to the ProducerFlow task 360 instance 260 that cannot continue processing until there is room to store an item 315 in the item queue 410. In an aspect of this embodiment and example the shared queue callback wrapper 400 queues the concurrency ticket 280 for the ProducerFlow task 360 instance 260 that cannot continue processing until there is room to store an item 315 in the item queue 410.
While the following discussion is made with respect to systems portrayed herein the operations described may be implemented in other systems. The operations described herein are not limited to the order shown. Additionally, in other alternative embodiments more or fewer operations may be performed.
Referring to
In an embodiment and the example the start of the consumer task 502 initiates the execution of all currently defined consumer task 380 instances 260. In an embodiment and the example the start of the producer task 504 initiates the execution of all currently defined producer task 360 instances 260.
In an embodiment and the example the ProducerFlow task 360 produces an item 512 and then stores the item, i.e., enqueues the item, to a queue 514. In an embodiment and the example the ProducerFlow task 360 executes in a loop producing 512 and enqueuing 514 items.
In an embodiment and the example the ConsumerFlow task 380 retrieves an item, i.e., dequeues an item, from a queue, 522 and thereafter processes the retrieved item 524. In an embodiment and the example the ConsumerFlow task 380 executes in a loop dequeuing items 522 and processing the dequeued items 524.
In an embodiment and the example when a ProducerFlow task 360 instance 260 initiates an enqueue 514 of an item, a SharedQueue Callback wrapper 530 of
Referring to
In an embodiment and the example the processing thread for the calling task instance is released, e.g., to a thread pool, 532. Thus, in an embodiment and the example if a ProducerFlow task 360 instance 260 has initiated an enqueue 514 the SharedQueue Callback wrapper 530 manages the release 532 of the processing thread 130 for the ProducerFlow task 360 instance 260. In an embodiment and the example if a ConsumerFlow task 380 instance 260 has initiated a dequeue 522 the SharedQueue Callback wrapper 530 manages the release 532 of the processing thread 130 for the ConsumerFlow task 380 instance 260.
In an embodiment and the example an identification of the task instance that initiated the SharedQueue Callback wrapper processing is stored in a task callback queue 534. Thus, in an embodiment and the example if a ProducerFlow task 360 instance 260 has initiated the SharedQueue Callback wrapper processing an identification of the ProducerFlow task 360 instance 260 is stored in a producer callback queue 420. In an embodiment and the example if a ConsumerFlow task 380 instance 260 has initiated the SharedQueue Callback wrapper processing an identification of the ConsumerFlow task 380 instance 260 is stored in a consumer callback queue 430.
In an embodiment and the example if a ProducerFlow task instance has initiated the SharedQueue Callback wrapper processing the item produced by the ProducerFlow task instance is also stored, or otherwise referenced, in the producer callback queue 534.
In an embodiment and the example the calling task instance is removed from or otherwise disassociated with memory 536, and thus, for execution purposes, ceases to exist.
In an embodiment and the example at decision block 538 a determination is made as to whether there is room in the item queue to store a produced item. If yes, in an embodiment and the example at decision block 540 a determination is made as to whether there is a ProducerFlow task instance queued to the producer callback queue; i.e., whether there is a ProducerFlow task instance that currently desires to enqueue an item. If yes, in an embodiment and the example, and referring to
In an embodiment and the example the item produced by the dequeued ProducerFlow task instance is enqueued to the item queue 552.
In an embodiment and the example a callback is initiated for the dequeued ProducerFlow task instance 554.
In an embodiment and the example, the callback will cause, or otherwise initiate, the reconstitution of the dequeued ProducerFlow task instance in memory 570, for continuing execution. In an embodiment and the example, the callback will cause, or otherwise initiate, a thread assignment to the dequeued ProducerFlow task instance 572. In an embodiment and the example, the callback will cause, or otherwise initiate, processing flow control to resume within the dequeued ProducerFlow task instance 574, e.g., at the yield return 370.
In an embodiment the SharedQueue Callback wrapper processing is ended 546.
Referring again to
In an embodiment and the example an item stored in the item queue is retrieved, i.e., dequeued, for the dequeued ConsumerFlow task instance 562.
In an embodiment and the example a callback is initiated for the dequeued ConsumerFlow task instance 564.
In an embodiment and the example the callback will cause, or otherwise initiate, the reconstitution of the dequeued ConsumerFlow task instance in memory 570, for continuing execution. In an embodiment and the example the callback will cause, or otherwise initiate, a thread assignment to the dequeued ConsumerFlow task instance 572. In an embodiment and the example the callback will cause, or otherwise initiate, processing flow control to resume within the dequeued ConsumerFlow task instance 574, e.g., at the yield return 386. In an embodiment and the example as part of the re-initiation of ConsumerFlow task instance processing flow control the retrieved item from the item queue is provided to the ConsumerFlow task instance 574.
In an embodiment the SharedQueue Callback wrapper processing is ended 546.
Referring again to
As can be seen from this exemplary logic flow the start order of the tasks, i.e., the ProducerFlow task 360 and the ConsumerFlow task 380, is immaterial. If the ConsumerFlow task 380 starts first and a ConsumerFlow task 380 instance 260 initiates the dequeue 522 of an item 315 but there are no items 315 currently stored in the item queue 410, e.g., because no ProducerFlow task 360 instance 260 has yet to execute to produce 512 and enqueue 514 an item 315, the ConsumerFlow task 380 instance 260 is enqueued 534 to the consumer callback queue 430 until an item 315 becomes available to retrieve 522. In an embodiment while a task instance 260 is enqueued 534 to a task callback queue, e.g., exemplary producer callback queue 420 or exemplary consumer callback queue 430, the task instance 260 is not utilizing resources, e.g., a processing thread 130 or system memory 150, that can be otherwise utilized by other task processing.
Processing control returns to a ProducerFlow task 635 instance 260 from the asynchronous execution of enqueuing an item on the item queue at the yield return task call 628.
Processing control returns to a ConsumerFlow task 640 instance 260 from the asynchronous execution of dequeuing an item from the item queue at the yield return task call 648.
A callback is generated for the ProducerFlow task 635 at code line 662 of
Referring to
The ProducerConsumerQueue wrapper 660 execution can also check 670 to determine if there is any room in the item queue 410 to enqueue 312 an item 315 produced by a ProducerFlow task 635 instance 260. If yes, a ProducerFlow task 635 instance 260 is dequeued 672 from the Producer callback queue 420 and the item 315 produced by the dequeued ProducerFlow task 635 instance 260 is enqueued in the item queue 410.
In an embodiment and the example, if the ProducerConsumerQueue wrapper 660 execution is invoked by a ProducerFlow task 635 instance 260 but there is currently no room to store items 315 in the item queue 410 the ProducerConsumerQueue wrapper 660 enqueues 674 the calling ProducerFlow task 635 instance 260 to the Producer callback queue 420.
Referring to
In an embodiment and the example, if the ProducerConsumerQueue wrapper 660 execution is invoked by a ConsumerFlow task 640 instance 260 but there is currently no items 315 stored in the item queue 410 the ProducerConsumerQueue wrapper 660 enqueues 686 the calling ConsumerFlow task 640 instance 260 to the Consumer callback queue 430.
As previously noted, although the discussion herein for an embodiment alf system 200 has been within a consumer-producer model as depicted in
The embodiment computing device system 700 includes a bus 705 or other mechanism for communicating information, and a processing unit 710, also referred to herein as a processor 710, coupled with the bus 705 for processing information. The computing device system 700 also includes system memory 150, which may be volatile or dynamic, such as random access memory (RAM), non-volatile or static, such as read-only memory (ROM) or flash memory, or some combination of the two. The system memory 150 is coupled to the bus 705 for storing information and instructions 220 to be executed by the processing unit 710, and may also be used for storing temporary variables or other intermediate information during the execution of instructions by the processor 710. The system memory 150 often contains an operating system and one or more programs, or applications, and/or software code, 220 and may also include program data 220.
In an embodiment a storage device 720, such as a magnetic or optical disk, solid state drive, flash drive, etc., is also coupled to the bus 705 for storing information, including program code of instructions 220 and/or data, e.g., volumes. In the embodiment computing device system 700 the storage device 720 is computer readable storage, or machine readable storage, 720.
Embodiment computing device systems 700 generally include one or more display devices 735, such as, but not limited to, a display screen, e.g., a cathode ray tube (CRT) or liquid crystal display (LCD), a printer, and one or more speakers, for providing information to the computing device's system administrators and users. Embodiment computing device systems 700 also generally include one or more input devices 730, such as, but not limited to, a keyboard, mouse, trackball, pen, voice input device(s), and touch input devices, which the system administrators and users can utilize to communicate information and command selections to the processor 710. All of these devices are known in the art and need not be discussed at length here.
The processor 710 executes one or more sequences of one or more programs, or applications, and/or software code instructions 220 resident in the system memory 150. These instructions 220 may be read into the system memory 150 from another computing device-readable medium, including, but not limited to, the storage device 720. In alternative embodiments, hard-wired circuitry may be used in place of or in combination with software instructions. Embodiment computing device system 700 environments are not limited to any specific combination of hardware circuitry and/or software.
The term “computing device-readable medium” as used herein refers to any medium that can participate in providing program, or application, and/or software instructions 220 to the processor 710 for execution. Such a medium may take many forms, including but not limited to, storage media and transmission media. Examples of storage media include, but are not limited to, RAM, ROM, EEPROM, flash memory, solid state drive, CD-ROM, USB stick drives, digital versatile disks (DVD), magnetic cassettes, magnetic tape, magnetic disk storage, or any other magnetic medium, floppy disks, flexible disks, punch cards, paper tape, or any other physical medium with patterns of holes, memory chip, or cartridge. The system memory 150 and storage device 720 of embodiment computing device systems 700 are further examples of storage media. Examples of transmission media include, but are not limited to, wired media such as coaxial cable(s), copper wire and optical fiber, and wireless media such as optic signals, acoustic signals, RF signals and infrared signals.
An embodiment computing device system 700 also includes one or more communication connections 750 coupled to the bus 705. Embodiment communication connection(s) 750 provide a two-way data communication coupling from the computing device system 700 to other computing devices on a local area network (LAN) 765 and/or wide area network (WAN), including the world wide web, or internet, 770 and various other communication networks 775, e.g., SMS-based networks, telephone system networks, etc. Examples of the communication connection(s) 750 include, but are not limited to, an integrated services digital network (ISDN) card, modem, LAN card, and any device capable of sending and receiving electrical, electromagnetic, optical, acoustic, RF or infrared signals.
Communications received by an embodiment computing device system 700 can include program, or application, and/or software instructions and data 220. Instructions 220 received by the embodiment computing device system 700 may be executed by the processor 710 as they are received, and/or stored in the storage device 720 or other non-volatile storage for later execution.
While various embodiments are described herein, these embodiments have been presented by way of example only and are not intended to limit the scope of the claimed subject matter. Many variations are possible which remain within the scope of the following claims. Such variations are clear after inspection of the specification, drawings and claims herein. Accordingly, the breadth and scope of the claimed subject matter is not to be restricted except as defined with the following claims and their equivalents.
This application is related to commonly assigned, co-pending U.S. patent application Ser. No. 13/028,552, (docket no. MS331591.01), entitled “Improved Asynchronous Programming Execution”, which is incorporated herein by reference in its entirety.