If you can't read please download the document
Upload
bilcorry
View
1.604
Download
4
Embed Size (px)
Citation preview
Blue Orange
Advanced Track:
Asynchronous Threads
Bil Corrylasso.pro
What Are Async Threads?
Code that executes in parallel to the currently processing page.
Why Use Async Threads?
Off-load tasksImprove response time to enduser by off-loading tasks that do not need to provide immediate feedback to the enduser
Recurring eventsLasso Scheduled Events, Email Queue, etc all are async threads.
Network-hooked serviceslp_site_restart sets up a TCP listener that receives commands to restart Lasso
Typical Lasso Request Model
Browser sends HTTP request to the web server
Web server determines the request is for Lasso and passes it to the Lasso connector
Lasso connector communicates with Lasso Server and sends the request
Lasso Server parses request, replies to Lasso connector
Lasso connector replies to web server
Web server replies to browser
Lasso Async Thread Model
Lasso page initiates new thread
Just like a normal page, the thread will run until:It terminates normally
It crashes
It is terminated for taking too long
Lasso site or server is shut down
When configured as such, some threads never terminate
Lasso Async Thread Model
(cont)
Because the request comes from Lasso itself, async threads do NOT have access to the web request info, such as client_headers, action_params, etc.
It will also not have access to the variables of the page that created it.
All file paths must be absolute from the hard disk root [include] does not work
Lasso Async Thread Model
(cont)
Output from the async thread is not available, so alternative methods must be used, such as logging to a file, a database, global variable or the Lasso console
An async thread will execute according to its priority and the load on Lasso
Basic Example
Async threads are surrounded by curly-braces and initiated using ->asasync:
[{'Hello World'}->asasync]
The above code doesn't show anything in the browser, but it does run asynchronously.
Sending Data to Async Thread
->asasync allows you to add params to pass into the async thread
[{ var('p1') = params->find('p1')->get(1)->value }->asasync(-params=array('p1'=1, 'p2'=2))]
Can also use globals (or other shared resources), but take care to correctly send the right message to the right thread and use [thread_atomic] to keep access to the global thread-safe
Template For Copying Vars To Async Thread
Creating Context
To create context within async threads, use variables to store the context of the current page (such as client_headers, file path, action_params) and use the template to pass the context into the async thread.
Two Important Settings
[Lasso_ExecutionTimeLimit]Specifies the maximum number of seconds to let this thread run. Setting it to zero will allow the thread to run continuously
[Thread_SetPriority]Can set to high or low, setting it to low (Thread_Priority_Low) gives more priority to enduser requests
Off-Loading Tasks
Improve the response time to the enduser by off-loading tasks on the page that meet the following criteria:Code for task is relatively self-contained
Task does not need to return data for the enduser to view
Task does not have to be finished by the time the concurrent page is served
Example of Off-Loading a Task
Page originally created related records and made the enduser wait:
[
loop(500);// create related recordinline(-sql=INSERT INTO mytable (id,this,that)\ VALUES (+integer($userid)+,+integer($this)+,+integer($that)+)); /loop;
'Thanks for waiting!';
]
Example of Off-Loading a Task
(cont)
Page now off-loads the related records creation and response much quicker to the enduser:
Creating a Recurring Event
Use [while(true)] to create a continuous thread
Use [Lasso_ExecutionTimeLimit(0)] to permit the thread to run continuously
Can use a global to use as a switch to shut down the thread [while(global('on'))] just be sure to use [thread_atomic] to make it thread-safe
Use [sleep] to pause the event between runsVery important! If the thread doesn't sleep, it will consume Lasso and the processor
Example of a Recurring Event
Creating a thread to watch a folder for new files to process:
[{Lasso_ExecutionTimeLimit(0); // run foreverThread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // low prioritywhile(true);iterate(file_listdirectory('///path/from/disk/root/'),local('file'));// do something with #file/iterate;Sleep(1000*60*10); // sleep 10 minutes (in milliseconds)/while;}->asasync]
This would be placed in your LassoStartup folder.
Debugging
Async threads are tricky to debug because they do not directly output the browser. Test async code outside of ->asasync
Trap for errors
Send debug messages to an external source (file, database, etc.)
Test Outside of Async
Easiest testing method, comment out the ->asasync container and try running your code, does it work?
For recurring event threads, you'll have to limit the number of loop_counts and shorten the sleep:
[//{Lasso_ExecutionTimeLimit(0); // run foreverThread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // low prioritywhile(true);loop_count > 10 ? loop_abort;iterate(file_listdirectory('///path/from/disk/root/'),local('file'));// do something with #file/iterate;Sleep(1000*60*2); // sleep 2 minutes (in milliseconds)/while;//}->asasync]
Trapping for Errors
Place async code within [protect] to log errors:
[{Lasso_ExecutionTimeLimit(0); // run foreverThread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // low priority
protect;handle_error;log_critical('Folder watcher encounter an error: '+error_msg);/handle_error;
while(true);iterate(file_listdirectory('///path/from/disk/root/'),local('file'));// do something with #file/iterate;Sleep(1000*60*10); // sleep 10 minutes (in milliseconds)/while;/protect;}->asasync]
Send Debug Messages to External Source
File
Database
Lasso Errors
Lasso Console
Global Var
Thank You!
Questions?