-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add apply_*
functions to the timer
module that accept anonymous functions
#7649
Conversation
CT Test Results 2 files 91 suites 41m 23s ⏱️ Results for commit 4e97963. ♻️ This comment has been updated with latest results. To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
Btw, I changed the tests for the related functions a little. Timer tests are slow by nature, and running the |
I added another commit to document caveats related to the use of |
I just realized that If the function denoted by the given Also, if the given I think this should at least be documented, and followed up by a mechanism to update running |
For the sake of code upgrades |
Yes, I understand that :) My point is that, with timers involved there is a wide field of mistakes, unexpected things, or consequences that you were not aware of, which could pop up after a hot upgrade. A timed function will be executed later, so any misbehavior like old code being executed or failing calls to code which went out of the code server would not be detected straight away, maybe not for a long time even. And as the calls are made in processes somewhat removed or dislocated from everything that is upgraded, this is not easy to detect even. Timed calls would just keep doing the old stuff, or fail to execute altogether, without anyone the wiser. |
What is the status of this PR, I wonder? I think it is a pretty useful addition, for the reasons @michalmuskala named and others. |
I am generally in favour of this PR, but I might have some nits to pick regarding the documentation. I'll try to get to it early next week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good to me, but I think that the functions that take both a fun and arguments are unnecessary and just clutter up the API with more functions than needed.
<p>Evaluates <c>spawn(erlang, apply, [<anno>Function</anno>, | ||
[]])</c> after <c><anno>Time</anno></c> milliseconds.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<p>Evaluates <c>spawn(erlang, apply, [<anno>Function</anno>, | |
[]])</c> after <c><anno>Time</anno></c> milliseconds.</p> | |
<p>Evaluates <c>spawn(<anno>Function</anno>)</c> | |
after <c><anno>Time</anno></c> milliseconds.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, while that has the same outcome, spawn(Function)
is not what it does. It does call spawn(erlang, apply, [Function, []])
, as it currently says.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK.
lib/stdlib/doc/src/timer.xml
Outdated
<name name="apply_after" arity="3" since=""/> | ||
<fsummary>Spawn a process evaluating <c>erlang:apply(Function, Arguments)</c> | ||
after a specified <c>Time</c>.</fsummary> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should have this function (nor the other ones that take both a fun and arguments). We don't use this style for the lists
module or for spawn
, so I don't think we should use it here.
(I see that timer:tc()
since OTP 26.0 has variants that take both a fun and arguments. Being a family functions that is often use interactively, there is some justification for having extra convenience functions.)
lib/stdlib/doc/src/timer.xml
Outdated
<seemfa marker="#apply_after/4"><c>apply_after/4</c></seemfa>, | ||
<seemfa marker="#apply_interval/4"><c>apply_interval/4</c></seemfa>, and | ||
<seemfa marker="#apply_repeatedly/4"><c>apply_repeatedly/4</c></seemfa> | ||
are executed in an own process, and therefore calls to <c>self()</c> in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"an own" feels strange to me:
are executed in an own process, and therefore calls to <c>self()</c> in | |
are executed in its own process, and therefore calls to <c>self()</c> in |
or perhaps it would be better for clarity to write: "in a freshly-spawned process"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking a little bit more (and re-reading the previous comments for this PR), I now realize that the functions taking both funs and arguments are indeed needed useful and needed if you want to support hot code loading and need to pass in an external fun.
Thanks for your comments and suggestions @bjorng, I'll see to it next week as I am currently on vacation :) |
Here is the ticket id to use for the |
1828895
to
25a65af
Compare
@bjorng I added the ticket id to the since tags and used "a freshly-spawned process" instead of "an own process" as suggested above. |
Thanks! Looks good. Please squash the commits. |
25a65af
to
4e97963
Compare
Ok, done :) |
Added to our daily builds. |
Thanks for your pull request. |
This PR adds the functions
apply_after/2
,apply_interval/2
andapply_repeatedly/2
to thetimer
module that accept a 0-ary function as second argument, and the functionsapply_after/3
,apply_interval/3
andapply_repeatedly/3
that accept a n-ary function as second and a list of n arguments for this function as third arguments.This is mainly a convenience feature, the same can be achieved via eg
timer:apply_*(Time, erlang, apply, [Fun, Args])
, and internally the new functions use this approach.However, the new
timer
functions, when called, check the functions given to thetimer:apply_*/2
functions to be of arity0
, and the lengths of the argument lists given to thetimer:apply_*/3
functions to match the arities of the given functions.Using
timer:apply_*(Time, erlang, apply, [Fun, Args])
does no checking on being called, and mismatches are only discovered when the timer executes, without the process having calledtimer:apply_after/4
ever getting to know of it.