I have the following task
task body auto is
begin
Put_Line( licencepalte.all & " set off.");
delay traveltime.all;
Put_Line( licencepalte.all & " arrived.");
loop
select
indicator.passthrough;
terminate; -- error for this line: 'statement expected'
or
delay 0.2;
Put_Line( licencepalte.all & " is waiting.");
end select;
end loop;
end auto;
where we represent an indicator light and some cars (auto ~ automobiles) with tasks and protecteds. My main issue is, that I don't know, how to terminate, in case the indicator accepts the entry of the auto. You can see what I'm currently trying to do, and it pops up an error (see inline). How do I stop the task once the entry gets accepted? Why does this terminate not work? Thank you!
terminate is not an "action" that you perform. That is, you can't use a terminate statement anywhere you choose in the task body to terminate the task. The way to terminate a task is for the execution to reach the end that ends the body; in your case, exit to exit the loop works, as in Jacob's answer.
The purpose of or terminate is tell the program that a task is eligible for termination (I don't know if there's a better technical term for this). Suppose your task looks like:
task body Task_Type_1 is
begin
loop
select
accept Entry_1(...parameters...) do
-- something
end Entry_1;
or
accept Entry_2(...parameters...) do
-- something
end Entry_2;
end select;
end loop;
end Task_Type_1;
If the "something" code of the accept statements never exits the loop, the task will never terminate. This means that other constructs enclosing the task can never terminate. For example:
procedure Proc is
T1 : Task_Type_1;
begin
-- do some stuff
-- now we're at the end, and we have to wait for T1 to complete
end Proc;
The procedure creates a task of type Task_Type_1 and starts it. Then the body of the procedure is executed. When end Proc; is reached, the procedure doesn't terminate immediately, because it has to wait until the task finishes its job. But the way the task is written, the task will never complete. Therefore Proc will never return, and the program will probably deadlock.
or terminate is how to say that the task could terminate:
task body Task_Type_1 is
begin
loop
select
accept Entry_1(...parameters...) do
-- something
end Entry_1;
or
accept Entry_2(...parameters...) do
-- something
end Entry_2;
or
terminate;
end select;
end loop;
end Task_Type_1;
In this small example, where we have a procedure that just creates this one task, or terminate means: if this task reaches a point where it's blocked in the select because there aren't any entry calls waiting, and if Proc has reached the end of its code, then we terminate the task. The task body exits, any finalization that needs to be done is done, and then Proc can complete.
or terminate can be used only in a "selective accept". If you say select Some_Other_Task.Entry_2(...); so that it blocks until the other task's entry is available, you can't use or terminate in that kind of select.
In a more complex case, a procedure could create two or more tasks. When that procedure reaches its end statement, it won't return until (roughly speaking) all the tasks it creates are completed or all of the tasks that haven't completed are blocked on select statements that have or terminate clauses. If the latter happens, then all of those tasks complete and then the procedure can return.
The rule about "terminate alternatives" is in RM 9.3(6). It speaks in terms of depending on a master; in the example I showed above, Proc is the master.
If I understand your question correctly, an exit would do nicely instead of terminate.
Related
I'm running GenServer as a background job which is rescheduled each interval by Process.send_after(self(), :work, #interval).
This job is started by Supervisor when Application starts.
It's working perfectly, but now I want to test if my GenServer module is really spawning new process each interval.
How can I test it?
EDIT
I found that :sys.get_status(pid) can be use to fetch some data about process, but I would really like to use something like receive do ... end
EDIT 2
handle_info/2 function:
#impl true
def handle_info(:work, state) do
do_smt()
schedule_worker()
{:noreply, state}
end
schedule_worker/0 function:
defp schedule_worker do
Process.send_after(self(), :work, #interval)
end
There's something missing in your message. From what you have posted we can understand that every #interval milliseconds a :work message is sent. You are not telling us what the handle_info/2 is supposed to do when the message is dispatched.
Once this is defined, you can definitely write a test to assert that a message has been received by using the assert_received assertion.
I would test do_smt() by using Mock library and writing a test that makes as assertion like the following:
with_mock(MyModule, [do_stm_else: fn -> :ok]) do
do_smt()
assert_called MyModule.do_stm_else()
end
In this way, you have called the function that the task should execute, so you can assume that the task creation is being called.
If you want to let the do_stm_else function communicate with your test (in this scenario it looks a bit overengineered) you should:
get the pid of the test by calling self()
Pass the pid to the mock function to get it used
use assert_receive to verify that the communication has occurred
pid = self()
with_mock(MyModule, [do_stm_else: fn ->
Process.send(pid, :msg)
]) do
do_smt()
assert_called MyModule.do_stm_else()
end
assert_receive(:msg)
Please note that I had no time to check this, you should spend a bit to investigate.
I want to create a task that reads from a file for a few minutes while the main thread does other things. But I'd like the main thread to be able to poll the task to see if it is "Busy" or not (a Boolean value) without blocking the main thread.
I have a naive attempt here, which does work but it leaves the Busy flag completely exposed to be toggled at will by the main thread (this is not safe)...
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
task type Non_Blocking_Reader_Task (Busy : access Boolean) is
entry Read (Destination : in Natural);
end Non_Blocking_Reader_Task;
task body Non_Blocking_Reader_Task is
begin
loop
select
when not Busy.all =>
accept Read (Destination : in Natural) do
Busy.all := True;
end Read;
for i in 1 .. 50 loop
Put ("."); -- pretend to do something useful
delay 0.1; -- while wasting time
end loop;
Busy.all := False;
end select;
end loop;
end Non_Blocking_Reader_Task;
Reader_Busy_Volatile : aliased Boolean;
Reader : Non_Blocking_Reader_Task (Reader_Busy_Volatile'Access);
begin
Put_Line (Reader_Busy_Volatile'Image);
Reader.Read (123);
for i in 1 .. 15 loop
Put_Line (Reader_Busy_Volatile'Image);
delay 0.5;
end loop;
abort Reader;
end Main;
My second idea was to create a protected type and hide the flag and the task inside it, but this is not permitted by the language.
Question
How can I create a protected "task is busy" flag that can is read-only from the main thread and read/write from the task (which does not cause the main thread to block)?
Edit:
The solution!
My revised (working) solution based on the stirling advice of #flyx :)
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
task type Reader_Task is
entry Read (Destination : in Natural);
entry Join;
entry Ready;
end Reader_Task;
task body Reader_Task is
Dest : Natural;
begin
loop
select
accept Read (Destination : in Natural) do
Dest := Destination;
end Read;
-- we only get here after a Read has been received.
for i in 1 .. 5 loop
Put ("."); -- pretend to do something useful
delay 1.0; -- while wasting time
end loop;
or
accept Join;
or
accept Ready;
or
terminate;
end select;
end loop;
end Reader_Task;
Reader : Reader_Task;
begin
-- first call will not block.
Reader.Read (123);
Put_Line ("MAIN: Reading in progress on second thread");
for i in 1 .. 12 loop
select
-- NON-BLOCKING CALL!
Reader.Ready; -- test if task is busy
Put_Line ("MAIN: NON-BLOCKING CALL SUCCEEDED -- TASK IS NOT BUSY");
else
Put_Line ("MAIN: NON-BLOCKING CALL FAILED -- TASK IS BUSY");
end select;
delay 1.0;
end loop;
Put_Line ("Main: Waiting for Reader (BLOCKING CALL)...");
Reader.Join;
Put_Line ("Main: all finished!");
end Main;
I've added two more entries to the task: Join and Ready which are basically the same but for the names. Join reminds me to do a blocking call to it, and Ready indicates that a non-blocking call is suitable for testing task availability. I've done this because there are times when I want to know if the previous run of Read() has finished without firing off a new one. This lets me do this neatly and all without any discrete flags at all! Awesome.
In Ada, the caller decides whether an entry call is blocking or not. You should not try and implement code for checking this inside the task.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
task type Reader_Task is
entry Read (Destination : in Natural);
end Reader_Task;
task body Reader_Task is
begin
loop
select
accept Read (Destination : in Natural) do
null;
-- store Destination (?)
end Read;
or
-- allow task to be terminated while waiting
terminate;
end select;
-- we only get here after a Read has been received.
for i in 1 .. 50 loop
Put ("."); -- pretend to do something useful
delay 0.1; -- while wasting time
end loop;
end loop;
end Reader_Task;
Reader : Reader_Task;
begin
-- first call will not block.
Reader.Read (123);
for i in 1 .. 15 loop
-- check whether Read can be called immediately and if yes,
-- call it.
select
Reader.Read (456);
else
-- Read is not available, do something else.
null;
end select;
delay 0.5;
end loop;
-- don't call abort; let Reader finish its current task.
-- Reader will be terminated once it waits on the terminate alternative
-- since the parent is finished.
end Main;
The select … else … end select structure is Ada's way of doing a non-blocking call. You don't use a flag for signalling that the task is ready to receive an entry call because potentially, this state could change between the query of the flag and the actual call of the entry. select has been designed to avoid this problem.
I am trying to implement multitasking to lua, so that I can use multiple Threads on the Node MCU.
My idea was to run the threads as functions, pause them and continue with the next and do that in a loop. The debug.sethook function seemed prommising but didn't work with the corutines, they executed the hook only after the corutine finished.
I only really need a way to pause a functon.
mt = {}
mt.threadList = {}
function mt.newThread(fnc)
table.insert(mt.threadList,fnc)
end
function mt.update()
for i=1,#mt.threadList do
print("EPOCH: "..i)
debug.sethook(print,"c",40)
coroutine.resume( mt.threadList[i] )
debug.sethook()
end
end
function tA()
for i=1,100 do
print("A",i)
end
end
function tB()
for i=1,100 do
print("B",i)
end
end
mt.newThread(tA)
mt.newThread(tB)
mt.update()
coroutine.resume continues a coroutine, not a regular function. Coroutines (from the Lua side) are generated by coroutine.create. coroutine.resume can only be called on the value returned by coroutine.create.
That being said, Lua coroutines are cooperative (hence the term "co-routine"). That means that you're not supposed to be able to arbitrarily interrupt their execution at any particular point. The coroutine itself should decide when to suspend, via a call to coroutine.yield or similar functions.
You can use debug.sethook on a coroutine to set its debug hook (if you don't pass a coroutine to sethook, then it assumes that you're setting the debug hook for the current thread, which is not what you want), and thereby coroutine.yield at arbitrary points in time. But you really shouldn't.
In any case, without coroutines, there is no way to "pause" a function's execution at all. Not even with a debug hook.
I want to exit execution of Lua script on some condition .
Example :
content = get_content()
if not content then
-- ( Here i want some kind of exit function )
next_content = get_content()
--example there can lot of further checks
Here I want that if I am not getting content my script suppose to terminate is should not go to check to next.
Use os.exit() or just return from some "main" function if your script is embedded.
os.exit()
kill process by sending a signal
do return end
stop execution
The two methods are not equal if you want to write and execute some luacode in the interpreter after stopping the execution by launching your program using the -i flag.
th -i main.lua
extract from the lua api doc :
For syntactic reasons, a break or return can appear only as the last statement of a block (in other words, as the last statement in your chunk or just before an end, an else, or an until). For instance, in the next example, break is the last statement of the then block.
local i = 1
while a[i] do
if a[i] == v then break end
i = i + 1
end
Usually, these are the places where we use these statements, because any other statement following them is unreachable. Sometimes, however, it may be useful to write a return (or a break) in the middle of a block; for instance, if you are debugging a function and want to avoid its execution. In such cases, you can use an explicit do block around the statement:
function foo ()
return --<< SYNTAX ERROR
-- `return' is the last statement in the next block
do return end -- OK
... -- statements not reached
end
In lua 5.2.0-beta-rc1+, you can add a label at the end of your code called ::exit:: or something of the like, and then whenever you need to exit the program just call it like this:
goto exit
My Rails web app has dozens of methods from making calls to an API and processing query result. These methods have the following structure:
def method_one
batch_query_API
process_data
end
..........
def method_nth
batch_query_API
process_data
end
def summary
method_one
......
method_nth
collect_results
end
How can I run all query methods at the same time instead of sequential in Rails (without firing up multiple workers, of course)?
Edit: all of the methods are called from a single instance variable. I think this limits the use of Sidekiq or Delay in submitting jobs simultaneously.
Ruby has the excellent promise gem. Your example would look like:
require 'future'
def method_one
...
def method_nth
def summary
result1 = future { method_one }
......
resultn = future { method_nth }
collect_results result1, ..., resultn
end
Simple, isn't it? But let's get to more details. This is a future object:
result1 = future { method_one }
It means, the result1 is getting evaluated in the background. You can pass it around to other methods. But result1 doesn't have any result yet, it is still processing in the background. Think of passing around a Thread. But the major difference is - the moment you try to read it, instead of passing it around, it blocks and waits for the result at that point. So in the above example, all the result1 .. resultn variables will keep getting evaluated in the background, but when the time comes to collect the results, and when you try to actually read these values, the reads will wait for the queries to finish at that point.
Install the promise gem and try the below in Ruby console:
require 'future'
x = future { sleep 20; puts 'x calculated'; 10 }; nil
# adding a nil to the end so that x is not immediately tried to print in the console
y = future { sleep 25; puts 'y calculated'; 20 }; nil
# At this point, you'll still be using the console!
# The sleeps are happening in the background
# Now do:
x + y
# At this point, the program actually waits for the x & y future blocks to complete
Edit: Typo in result, should have been result1, change echo to puts
You can take a look at a new option in town: The futoroscope gem.
As you can see by the announcing blog post it tries to solve the same problem you are facing, making simultaneous API query's. It seems to have pretty good support and good test coverage.
Assuming that your problem is a slow external API, a solution could be the use of either threaded programming or asynchronous programming. By default when doing IO, your code will block. This basically means that if you have a method that does an HTTP request to retrieve some JSON your method will tell your operating system that you're going to sleep and you don't want to be woken up until the operating system has a response to that request. Since that can take several seconds, your application will just idly have to wait.
This behavior is not specific to just HTTP requests. Reading from a file or a device such as a webcam has the same implications. Software does this to prevent hogging up the CPU when it obviously has no use of it.
So the question in your case is: Do we really have to wait for one method to finish before we can call another? In the event that the behavior of method_two is dependent on the outcome of method_one, then yes. But in your case, it seems that they are individual units of work without co-dependence. So there is a potential for concurrency execution.
You can start new threads by initializing an instance of the Thread class with a block that contains the code you'd like to run. Think of a thread as a program inside your program. Your Ruby interpreter will automatically alternate between the thread and your main program. You can start as many threads as you'd like, but the more threads you create, the longer turns your main program will have to wait before returning to execution. However, we are probably talking microseconds or less. Let's look at an example of threaded execution.
def main_method
Thread.new { method_one }
Thread.new { method_two }
Thread.new { method_three }
end
def method_one
# something_slow_that_does_an_http_request
end
def method_two
# something_slow_that_does_an_http_request
end
def method_three
# something_slow_that_does_an_http_request
end
Calling main_method will cause all three methods to be executed in what appears to be parallel. In reality they are still being sequentually processed, but instead of going to sleep when method_one blocks, Ruby will just return to the main thread and switch back to method_one thread, when the OS has the input ready.
Assuming each method takes two 2 ms to execute minus the wait for the response, that means all three methods are running after just 6 ms - practically instantly.
If we assume that a response takes 500 ms to complete, that means you can cut down your total execution time from 2 + 500 + 2 + 500 + 2 + 500 to just 2 + 2 + 2 + 500 - in other words from 1506 ms to just 506 ms.
It will feel like the methods are running simultanously, but in fact they are just sleeping simultanously.
In your case however you have a challenge because you have an operation that is dependent on the completion of a set of previous operations. In other words, if you have task A, B, C, D, E and F, then A, B, C, D and E can be performed simultanously, but F cannot be performed until A, B, C, D and E are all complete.
There are different ways to solve this. Let's look at a simple solution which is creating a sleepy loop in the main thread that periodically examines a list of return values to make sure some condition is fullfilled.
def task_1
# Something slow
return results
end
def task_2
# Something slow
return results
end
def task_3
# Something slow
return results
end
my_responses = {}
Thread.new { my_responses[:result_1] = task_1 }
Thread.new { my_responses[:result_2] = task_2 }
Thread.new { my_responses[:result_3] = task_3 }
while (my_responses.count < 3) # Prevents the main thread from continuing until the three spawned threads are done and have dumped their results in the hash.
sleep(0.1) # This will cause the main thread to sleep for 100 ms between each check. Without it, you will end up checking the response count thousands of times pr. second which is most likely unnecessary.
end
# Any code at this line will not execute until all three results are collected.
Keep in mind that multithreaded programming is a tricky subject with numerous pitfalls. With MRI it's not so bad, because while MRI will happily switch between blocked threads, MRI doesn't support executing two threads simultanously and that solves quite a few concurrency concerns.
If you want to get into multithreaded programming, I recommend this book:
http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601
It's centered around Java, but the pitfalls and concepts explained are universal.
You should check out Sidekiq.
RailsCasts episode about Sidekiq.