Asynchronous Threads in Lasso 8.5

1,597 views

Published on

Presentation at LDC09: Introduction to Asynchronous Threads in Lasso 8.5

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,597
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Asynchronous Threads in Lasso 8.5

  1. 1. Advanced Track: Asynchronous Threads Bil Corry lasso.pro
  2. 2. What Are Async Threads? Code that executes in parallel to the currently processing page.
  3. 3. Why Use Async Threads? <ul><li>Off-load tasks </li><ul><li>Improve response time to enduser by off-loading tasks that do not need to provide immediate feedback to the enduser </li></ul><li>Recurring events </li><ul><li>Lasso Scheduled Events, Email Queue, etc all are async threads. </li></ul><li>Network-hooked services </li><ul><li>lp_site_restart sets up a TCP listener that receives commands to restart Lasso </li></ul></ul>
  4. 4. Typical Lasso Request Model <ul><li>Browser sends HTTP request to the web server
  5. 5. Web server determines the request is for Lasso and passes it to the Lasso connector
  6. 6. Lasso connector communicates with Lasso Server and sends the request
  7. 7. Lasso Server parses request, replies to Lasso connector
  8. 8. Lasso connector replies to web server
  9. 9. Web server replies to browser </li></ul>
  10. 10. Lasso Async Thread Model <ul><li>Lasso page initiates new thread
  11. 11. Just like a normal page, the thread will run until: </li><ul><li>It terminates normally
  12. 12. It crashes
  13. 13. It is terminated for taking too long
  14. 14. Lasso site or server is shut down </li></ul><li>When configured as such, some threads never terminate </li></ul>
  15. 15. Lasso Async Thread Model (cont) <ul><li>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.
  16. 16. It will also not have access to the variables of the page that created it.
  17. 17. All file paths must be absolute from the hard disk root – [include] does not work </li></ul>
  18. 18. Lasso Async Thread Model (cont) <ul><li>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
  19. 19. An async thread will execute according to its priority and the load on Lasso </li></ul>
  20. 20. Basic Example Async threads are surrounded by curly-braces and initiated using ->asasyn c: [{'Hello World'}->asasync] The above code doesn't show anything in the browser, but it does run asynchronously.
  21. 21. 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
  22. 22. Template For Copying Vars To Async Thread <?LassoScript // from: http://www.lassotech.com/async // stuff on your page not async here... // -------------- BEGIN OF ASYNC CODE -------------- { // -------------- BEGIN OF ASYNC CODE -------------- // -------------------- // process async! // -------------------- // // NOTE: Code below this point is processed in it's own thread! // Lasso_ExecutionTimeLimit(60 * 60); // in seconds, set this to something reasonable Thread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // set priority // recreate vars - this makes all the vars on the page available to the async thread iterate: params->(find:'-vars')->(get:1)->value, local:'var'; (var: #var->name) = #var->value; /iterate; // do stuff here that you want in it's own thread... // -------------- END OF ASYNC CODE -------------- }->(asasync: -params=(array: '-vars' = vars)); // -------------- END OF ASYNC CODE -------------- // do more stuff on the current page... ?>
  23. 23. 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.
  24. 24. Two Important Settings <ul><li>[Lasso_ExecutionTimeLimit] </li><ul><li>Specifies the maximum number of seconds to let this thread run. Setting it to zero will allow the thread to run continuously </li></ul><li>[Thread_SetPriority] </li><ul><li>Can set to high or low, setting it to low (Thread_Priority_Low) gives more priority to enduser requests </li></ul></ul>
  25. 25. Off-Loading Tasks <ul>Improve the response time to the enduser by off-loading tasks on the page that meet the following criteria: <li>Code for task is relatively self-contained
  26. 26. Task does not need to return data for the enduser to view
  27. 27. Task does not have to be finished by the time the concurrent page is served </li></ul>
  28. 28. Example of Off-Loading a Task Page originally created related records and made the enduser wait: [ loop(500); // create related record inline(-sql=”INSERT INTO mytable (id,this,that) VALUES (”+integer($userid)+”,”+integer($this)+”,”+integer($that)+”)”); /loop; 'Thanks for waiting!'; ]
  29. 29. Example of Off-Loading a Task (cont) Page now off-loads the related records creation and response much quicker to the enduser: <?LassoScript // from: http://www.lassotech.com/async // -------------- BEGIN OF ASYNC CODE -------------- { // -------------- BEGIN OF ASYNC CODE -------------- Lasso_ExecutionTimeLimit(60 * 60); // in seconds, set this to something reasonable Thread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // set priority // recreate vars - this makes all the vars on the page available to the async thread iterate: params->(find:'-vars')->(get:1)->value, local:'var'; (var: #var->name) = #var->value; /iterate; loop(500); // create related record inline(-sql=”INSERT INTO mytable (id,this,that) VALUES (”+integer($userid)+”,”+integer($this)+”,”+integer($that)+”)”); /loop; // -------------- END OF ASYNC CODE -------------- }->(asasync: -params=(array: '-vars' = vars)); // -------------- END OF ASYNC CODE -------------- 'Thanks for waiting!'; ?>
  30. 30. Creating a Recurring Event <ul><li>Use [while(true)] to create a continuous thread
  31. 31. Use [Lasso_ExecutionTimeLimit(0)] to permit the thread to run continuously
  32. 32. 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
  33. 33. Use [sleep] to pause the event between runs </li><ul><li>Very important! If the thread doesn't sleep, it will consume Lasso and the processor </li></ul></ul>
  34. 34. Example of a Recurring Event Creating a thread to watch a folder for new files to process: [{ Lasso_ExecutionTimeLimit(0); // run forever Thread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // low priority 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; }->asasync] This would be placed in your LassoStartup folder.
  35. 35. Debugging Async threads are tricky to debug because they do not directly output the browser. <ul><li>Test async code outside of ->asasync
  36. 36. Trap for errors
  37. 37. Send debug messages to an external source (file, database, etc.) </li></ul>
  38. 38. 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 forever Thread_SetPriority(Thread_GetCurrentID, Thread_Priority_Low); // low priority while(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 ]
  39. 39. Trapping for Errors Place async code within [protect] to log errors: [{ Lasso_ExecutionTimeLimit(0); // run forever Thread_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]
  40. 40. Send Debug Messages to External Source <ul><li>File
  41. 41. Database
  42. 42. Lasso Errors
  43. 43. Lasso Console
  44. 44. Email
  45. 45. Global Var </li></ul>
  46. 46. Thank You! Questions?

×