Unexpected output in Tasking? - task

Why it is not sure for below code that task_1 should execute first then task_2 because task_1 which is in waiting state get first start message from main? but output is not predictable please help me to understand?
WITH Ada.Text_IO; -- Include Text_IO Library
WITH Ada.Integer_Text_IO; -- Include Integer Text_IO Library
PROCEDURE task_demo_02 IS
TASK TYPE intro_task (message1 : Integer) IS
ENTRY start; -- Entry Point Into The Task
END intro_task;
TASK BODY intro_task IS -- Task Body Definition
BEGIN
ada.text_io.put_line("waitng");
ACCEPT start; -- Entry Point Into The Task
Ada.Text_IO.put ( "Display from Task ");
Ada.Integer_Text_IO.put (message1, 1);
Ada.Text_IO.new_line;
END intro_task;
Task_1 : intro_task (message1 => 1);--activate
Task_2 : intro_task (message1 => 2);--activate
BEGIN
ada.Text_IO.put_line("main");
Task_1.start; --- first task_1 should execute
Task_2.start; --- then task_2 isn't it ?
END task_demo_02;

BEGIN
ada.Text_IO.put_line("main");
Task_1.start; --- first task_1 should execute
Your comment seems to assume that this will cause Task_1 to execute, and Task_1 will finish executing until it's done, and then the main program will go on to Task_2.start.
But that's not the case. Task_1.start means that Task_1 is now ready to execute. But at this point, there are two tasks ready to execute: Task_1, and the environment task, which is the task that's running task_demo_2. You can't really tell which task is run first (there are some dispatching policies that will specify how tasks get run in a case like this, but in general you can't tell). That means that task_demo_02 could keep running, which means Task_2.start will happen before Task_1continues. Or it could mean that Task_1 starts, but that the processor will split time between Task_1 and task_demo_02. Or, on a multi-processor system, they could both run in parallel.
If you want to write a program where the main program starts Task_1 and waits for it to finish, the most reliable way is to add another entry:
TASK TYPE intro_task (message1 : Integer) IS
entry Start;
entry Finish;
END intro_task;
Task_1.Start;
Task_1.Finish;
and then, at the end of intro_task, add
accept Finish;

Related

Openwhisk: request has not yet finished

I have a distributed Openwhisk setup, and when I execute a large number of functions simultaneously like this
wsk -i action invoke test -r -b
at some point instead of getting the actual result, I start getting the following message:
ok: invoked /_/test, but the request has not yet finished, with id
Any idea how I could force Openwhisk execute the function and still return the result regardless how long the invocation actually takes? Is there maybe some playbook variable responsible for timeout?
You can execute a function in non-blocking mode. In this case, you will get the activation ID immediately and function execution will happen in the background. You can then check/track the status of function execution with the activation ID.
Remove the "-b" option from the command.
Also, a function execution timeout is configurable (default 60s), if function execution requires more time to execute, you can define it while creating the function.
For per function limit you can specify below setting when creating the function.
-t, --timeout LIMIT the timeout LIMIT in milliseconds after which the action is terminated (default 60000)

Trying to execute a function using a timer but the compiler says the function is unused

I was trying to execute a function a few seconds in the future by using timer:apply_after() but when I tried to compile the module it threw an error.
For example, say I have a module with two functions - one that prints an age, and another that uses a timer to execute it at a future time.
-module(test).
-export([main/0]).
print_age(Age) ->
io:format("Your age: ~p~n", [Age]).
main() ->
timer:apply_after(2000, test, print_age, [20]).
When I compile the module, I get:
> c(test).
test.erl:4: Warning: function print_age/1 is unused
{ok,test}
Although there's nothing in the timer docs to indicate it, the function must be exported in order for the timer to execute it:
-module(test).
-export([main/0, print_age/1]).
print_age(Age) ->
io:format("Your age: ~p~n", [Age]).
main() ->
timer:apply_after(2000, test, print_age, [20]).
One could get around the compiler error by adding -compile({nowarn_unused_function, {print_age,1}}). to the top of the module, but then it'll turn into a runtime error when the timer attempts to execute the function:
=ERROR REPORT==== 6-Jun-2018::13:37:14 ===
Error in process <0.89.0> with exit value:
{undef,[{test,print_age,[20],[]}]}
I don't know all the inner details of how timer works, but this answer indicates that it's running in a gen_server in a separate process.
The timer module is a standard gen_server running in a separate process. All the function in the timer module are public interfaces that execute a hidden gen_server:call or gen_server:cast to the timer server. This is a common usage to hide the internal of a server and allow further evolutions without impact on existing applications.
It makes sense I guess, since the current process must be able to continue executing code, and which function to execute must be stored safely somewhere until the delay is passed. And since one module can only access a function in another module if it's been exported, the function to execute must be exported too.

How do I stop a running task in Dask?

When using Dask's distributed scheduler I have a task that is running on a remote worker that I want to stop.
How do I stop it? I know about the cancel method, but this doesn't seem to work if the task has already started executing.
If it's not yet running
If the task has not yet started running you can cancel it by cancelling the associated future
future = client.submit(func, *args) # start task
future.cancel() # cancel task
If you are using dask collections then you can use the client.cancel method
x = x.persist() # start many tasks
client.cancel(x) # cancel all tasks
If it is running
However if your task has already started running on a thread within a worker then there is nothing that you can do to interrupt that thread. Unfortunately this is a limitation of Python.
Build in an explicit stopping condition
The best you can do is to build in some sort of stopping criterion into your function with your own custom logic. You might consider checking a shared variable within a loop. Look for "Variable" in these docs: http://dask.pydata.org/en/latest/futures.html
from dask.distributed import Client, Variable
client = Client()
stop = Varible()
stop.put(False)
def long_running_task():
while not stop.get():
... do stuff
future = client.submit(long_running_task)
... wait a while
stop.put(True)

How can I ensure an operation runs before Rails exits, without using `at_exit`?

I have an operation that I need to execute in my rails application that before my Rails app dies. Is there a hook I can utilize in Rails for this? Something similar to at_exit I guess.
Ruby itself supports two hooks, BEGIN and END, which are run at the start of a script and as the interpreter stops running it.
See "What does Ruby's BEGIN do?" for more information.
The BEGIN documentation says:
Designates, via code block, code to be executed unconditionally before sequential execution of the program begins. Sometimes used to simulate forward references to methods.
puts times_3(gets.to_i)
BEGIN {
def times_3(n)
n * 3
end
}
The END documentations says:
Designates, via code block, code to be executed just prior to program termination.
END { puts "Bye!" }
Okay so I am making no guarantees as to impact because I have not tested this at all but you could define your own hook e.g.
ObjectSpace.define_finalizer(YOUR_RAILS_APP::Application, proc {puts "exiting now"})
Note this will execute after at_exit so the rails application server output will look like
Stopping ...
Exiting
exiting now
With Tin Man's solution included
ObjectSpace.define_finalizer(YOUR_RAILS_APP::Application, proc {puts "exiting now"})
END { puts "exiting again" }
Output is
Stopping ...
Exiting
exiting again
exiting now

How to use ssh_connection:exec in Erlang?

This is an interesting situation, focused on the behavior of erlang ssh modules. I had spent a few hours troubleshooting a problem that turned out to reveal that the Erlang ssh_connection *exec/4* function operates asynchronously.
If you issue the ssh_connection:exec/4 function to run a script that takes several seconds to complete, and then in your erlang program you close the ssh connection, the script execution will terminate. My expectation was that the ssh_connection:exec would be synchronous rather than asynchronous.
Because the time to complete the remote script invoked by ssh_connection:exec is unknown, I chose to not issue the closure ssh:close(). I would like to understand the consequences of that:
Will the gc clear it at some point ?
Will it stay open for good during the whole node existence ?
Is there a way to make the ssh_connection:exec synchronous, as I would believe it should be.
Here is an example of the test erl program that I used to verify this issue. As a script you can run a simple sleep 10 (sleep 10 seconds) to emulate a slow running program.
-module(testssh).
-export([test/5]).
test (ServerName, Port, Command, User, Password) ->
crypto:start(),
ssh:start(),
{ok, SshConnectionRef} = ssh:connect(ServerName, Port, [ {user, User}, {password, Password} , {silently_accept_hosts, true} ], 60000 ),
{ok, SshConnectionChannelRef} = ssh_connection:session_channel(SshConnectionRef, 60000),
Status = ssh_connection:exec(SshConnectionRef, SshConnectionChannelRef, Command, 60000),
ssh:close(SshConnectionRef).
Remote script:
#!/bin/sh
sleep 10
I never had to use the ssh application myself, but you should be reading something wrong, it is clear in the doc that the result will be delivered as messages to the caller:
[...] the result will be several messages according to the following pattern. Note that the last message will be a channel close message, as the exec request is a one time execution that closes the channel when it is done[...]
See http://www.erlang.org/doc/man/ssh_connection.html#exec-4
So after you call ssh_connection:exec/4 , test with a loop like this:
wait_for_response(ConnectionRef) ->
receive
{ssh_cm, ConnectionRef, Msg} ->
case Msg of
{closed, _ChannelId} ->
io:format("Done");
_ ->
io:format("Got: ~p", [Msg]),
wait_for_response(ConnectionRef)
end
end.
You should receive the command output, and other ssh messages, and finally a 'closed' message that is your signal that the ssh command has properly finished.

Resources