-
Notifications
You must be signed in to change notification settings - Fork 11
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
WIP: Concurrency design #247
Merged
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c5cbe67
Add first notes on rfork
katcipis 941b2c1
Add initial draft of concurrency with actor model
katcipis ec7bdb4
Add fan-out fan-in example
katcipis 05f4ba9
Add some ideas on error handling
katcipis 5e0830f
Add more TODO
katcipis 72f995f
Merge branch 'master' of github.com:NeowayLabs/nash into addConcurren…
katcipis 95a5840
Add more elaborated example
katcipis ddb99b0
Add info about how stdout is handled
katcipis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Proposal: Concurrency on Nash | ||
|
||
There has been some discussion on how to provide concurrency to nash. | ||
There is a [discussion here](https://github.com/NeowayLabs/nash/issues/224) | ||
on how concurrency could be added as a set of built-in functions. | ||
|
||
As we progressed discussing it seemed desirable to have a concurrency | ||
that enforced no sharing between concurrent functions. It eliminates | ||
races and forces all communication to happen explicitly, and the | ||
performance overhead would not be a problem to a high level language | ||
as nash. | ||
|
||
Converging to a no shared state between concurrent functions initiated | ||
the idea of using the current rfork built-in as a means to express | ||
concurrency on Nash. This would already be possible today, the idea | ||
is just to make it even easier, specially the communication between | ||
different concurrent processes. | ||
|
||
This idea enables an even greater amount of isolation between concurrent | ||
processes since rfork enables different namespaces isolation (besides memory), | ||
but it has the obvious fallback of not being very lightweight. | ||
|
||
Since the idea of nash is to write simple scripts this does not seem | ||
to be a problem. If it is on the future we can create lightweight concurrent | ||
processes (green threads) that works orthogonally with rfork. | ||
|
||
The prototype for the new rfork would be something like this: | ||
|
||
```sh | ||
chan <= rfork [ns_param1, ns_param2] (chan) { | ||
//some code | ||
} | ||
``` | ||
|
||
The code on the rfork block does not have access to the | ||
lexical outer scope but it receives as a parameter a channel | ||
instance. | ||
|
||
This channel instance can be used by the forked processes and | ||
by the creator of the process to communicate. We could use built-in functions: | ||
|
||
```sh | ||
chan <= rfork [ns_param1, ns_param2] (chan) { | ||
cwrite($chan, "hi") | ||
} | ||
|
||
a <= cread($chan) | ||
``` | ||
|
||
Or some syntactic extension: | ||
|
||
```sh | ||
chan <= rfork [ns_param1, ns_param2] (chan) { | ||
$chan <- "hi" | ||
} | ||
|
||
a <= <-$chan | ||
``` | ||
|
||
Since this channel is meant only to be used to communicate with | ||
the created process, it will be closed when the process exit: | ||
|
||
```sh | ||
chan <= rfork [ns_param1, ns_param2] (chan) { | ||
} | ||
|
||
# returns empty string when channel is closed | ||
<-$chan | ||
``` | ||
|
||
Fan out and fan in should be pretty trivial: | ||
|
||
```sh | ||
chan1 <= rfork [ns_param1, ns_param2] (chan) { | ||
} | ||
|
||
chan2 <= rfork [ns_param1, ns_param2] (chan) { | ||
} | ||
|
||
# waiting for both to finish | ||
<-$chan1 | ||
<-$chan2 | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
What about the blocking/nonblocking types of channel?
If only blocking channels are supported, then some builtin function to 'select' between then will be required. What do you think?
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.
Select would be great =D. Nothing against buffered channels either...just not thinking about it right now. Actually I'm supposing you are talking about the buffered channels, nonblocking channels do not exist on Go, when the channel is full it will also block, the only way to guarantee that you will never block is by using select + default.
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.
What I mean was blocking/non-blocking types of communication, sorry, but buffered channels and/or select are ways to achieve this in Go, but I don't know how much of Go semantics makes sense to export to nash.
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.
Ow I see. Erlang has only message delivery, like network datagrams, they are non blocking. The problem with non-blocking is that they infer some sort of queue on the receiver (on Erlang it is the process mailbox), because I can just send 10000 trillion messages without blocking.
Go makes this queue explicit and will still block the sender...not sure what model is better right now.