Skip to content

Commit 35f1cec

Browse files
committed
Updated functions to be more in line with erlang and elixir function calls
1 parent 44897c3 commit 35f1cec

File tree

9 files changed

+119
-220
lines changed

9 files changed

+119
-220
lines changed

README.md

Lines changed: 10 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
Experiment to reproduce Erlang style processes in browser. The api follows the one from Erlang. All are found on the `ProcessSystem` class
22

3-
One example is an implementation of a GenServer. The other example is 2 processes talking
4-
to each other.
5-
63
#### Usage
74

85
* First, import the ProcessSystem create a new instance of one.
@@ -49,8 +46,9 @@ to each other.
4946
* `link(pid) : void` - links the current process with the process from the given pid
5047
* `unlink(pid) : void` - unlinks the current process from the process from the given pid
5148
* `register(name, pid) : void` - registers the given name to the pid
52-
* `registered(name) : pid` - returns the pid registered by the given name or null if not registered
49+
* `whereis(name) : pid` - returns the pid registered by the given name or null if not registered
5350
* `unregister(pid) : void` - unregisters the names associated with the pid
51+
* `registered() : Array` - returns the liast of names that are registered
5452
* `pid()` : pid` - returns the current process's pid
5553
* `pidof(obj) : pid` - takes the input and tries to find the pid. Input can be a `pid`, `Process`, or name the pid is associated with
5654
* `send(pid, msg) : msg` - sends a message the the process represented by the pid
@@ -59,61 +57,18 @@ to each other.
5957
* `exit(reason)` - terminates the current process with the given reason.
6058
* `exit(pid, reason)` - tells the process with the pid to exit with the given reason
6159
* `error(reason)` - terminates the current process with an error
60+
* `process_flag(pid, flag, value)` - Sets flags on the given process.
6261
* `process_flag(flag, value)` - Sets flags on the current process.
6362
* Note: the only flag respected is the `Symbol.for("trap_exit")` flag. If value is `true`, then exit signals from linked processes are turned into messages and sent to the current processes mailbox. If value is `false`, the exit is treated as normal and terminates the process. Setting it to `true` is useful for supervising processes.
6463
* `put(key, value)` - Adds a value to the current process's dictionary
65-
* `get(key)` - Gets a value from the current process's dictionary
66-
* `get()` - Gets the current process's dictionary
64+
* `get(key, default_value = null)` - Gets a value from the current process's dictionary or the default if key not in dictionary
65+
* `get_process_dict()` - Gets the current process's dictionary
6766
* `get_keys()` - Gets all the keys from the current process's dictionary
68-
* `erase(key)` - Removes the key and the associated value from the current process`s dictionary
67+
* `get_keys(value)` - Gets all the keys from the current process's dictionary with the given value
68+
* `erase(key)` - Removes the key and the associated value from the current process's dictionary
6969
* `erase()` - Removes all entries from the current process's dictionary
70+
* `is_alive(pid)` - Returns if the given pid is alive
71+
* `make_ref()` - Returns a unique reference
72+
* `list()` - Returns a list of all the pids
7073

7174
* `ProcessSystem.run(fun, args, context = null)` - A static generator function used to wrap a normal function or generator. If fun is a function, it returns the value, if it's a generator, then it delegates yielding to the generator.
72-
73-
* GenServer
74-
* `start(module, args)` - Starts a GenServer with the given module and args
75-
* `start_link(module, args)` - Starts a GenServer with the given module and args
76-
* `call* (server, action)` - Sends the GenServer a action and waits for it to respond with a value.
77-
* `cast* (server, action)` - Sends the GenServer a action to update a value.
78-
* `stop (server)` - Stops the GenServer.
79-
* **Note**: Genserver expects a module the has the following functions:
80-
* `init(args)` - Must return an array containing a symbol and the initial state
81-
* `handle_call(action, from, state)` - Called when `GenServer.call` is called. This function is given the action, the pid of the calling process, and the current state. Must return `[reply, return_value, new_state]` where reply is a symbol ,usually `Symbol.for("reply"), the value to return to the process, and lastly, the new state of the GenServer.
82-
* `handle_cast(action, state)` - Called when `GenServer.cast` is called. his function is given the action, and the current state. Must return `[reply, return_value, new_state]` where reply is a symbol ,usually `Symbol.for("noreply")`, and lastly, the new state of the GenServer.
83-
84-
#### GenServer Example
85-
86-
An example of a Stack using a GenServer
87-
88-
```javascript
89-
const Processes = require("erlang-processes");
90-
self.system = self.system || new Processes.default.ProcessSystem();
91-
92-
const Stack = {
93-
init: function(args){
94-
return [Symbol.for("ok"), args];
95-
},
96-
97-
handle_call: function(action, pid, state){
98-
return [Symbol.for("reply"), state[0], state.slice(1)];
99-
},
100-
101-
102-
handle_cast: function(action, state){
103-
return [Symbol.for("noreply"), [action[1]].concat(state)];
104-
}
105-
}
106-
107-
self.system.spawn(function*(){
108-
const [ok, pid] = yield* ProcessSystem.run(GenServer.start, [Stack, ["hello"]]);
109-
110-
let a = yield* ProcessSystem.run(GenServer.call, [pid, "pop"]);
111-
console.log(a); // "hello"
112-
113-
let b = yield* ProcessSystem.run(GenServer.cast, [pid, ["push", "world"]]);
114-
console.log(b); // Symbol.for("ok")
115-
116-
let c = yield* ProcessSystem.run(GenServer.call, [pid, "pop"]);
117-
console.log(c); // "world"
118-
});
119-
```

examples/gen_server.html

Lines changed: 0 additions & 15 deletions
This file was deleted.

examples/gen_server.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "erlang-processes",
3-
"version": "1.0.2",
3+
"version": "2.0.0",
44
"description": "Erlang style processes in JavaScript",
55
"main": "lib/processes.js",
66
"jsnext:main": "src/index.js",

src/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ import ProcessSystem from "./processes/process_system";
22
import GenServer from "./processes/otp/gen_server";
33

44
export default {
5-
ProcessSystem,
6-
GenServer
5+
ProcessSystem
76
};

src/processes/otp/gen_server.js

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/processes/process.js

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class Process {
4343
let machine = this.main();
4444

4545
this.system.schedule(function() {
46-
function_scope.system.set_current(function_scope.pid);
47-
function_scope.run(machine, machine.next());
48-
}, this.pid);
46+
function_scope.system.set_current(function_scope.pid);
47+
function_scope.run(machine, machine.next());
48+
}, this.pid);
4949
}
5050

5151
*main() {
@@ -62,7 +62,9 @@ class Process {
6262
}
6363

6464
process_flag(flag, value){
65+
const old_value = this.flags[flag];
6566
this.flags[flag] = value;
67+
return old_value;
6668
}
6769

6870
is_trapping_exits(){
@@ -89,7 +91,9 @@ class Process {
8991
break;
9092
}
9193
}catch(e){
92-
this.exit(e);
94+
if(e.constructor.name != "MatchError"){
95+
this.exit(e);
96+
}
9397
}
9498
}
9599

@@ -105,43 +109,43 @@ class Process {
105109
if(is_sleep(value)){
106110

107111
this.system.delay(function() {
108-
function_scope.system.set_current(function_scope.pid);
109-
function_scope.run(machine, machine.next());
112+
function_scope.system.set_current(function_scope.pid);
113+
function_scope.run(machine, machine.next());
110114
}, value[1]);
111115

112116
}else if(is_receive(value) && receive_timed_out(value)){
113117

114118
let result = value[3]();
115119

116-
this.system.schedule(function() {
117-
function_scope.system.set_current(function_scope.pid);
118-
function_scope.run(machine, machine.next(result));
120+
this.system.schedule(function() {
121+
function_scope.system.set_current(function_scope.pid);
122+
function_scope.run(machine, machine.next(result));
119123
});
120124

121125
}else if(is_receive(value)){
122126

123127
let result = function_scope.receive(value[1]);
124128

125129
if(result === States.NOMATCH){
126-
this.system.suspend(function() {
127-
function_scope.system.set_current(function_scope.pid);
128-
function_scope.run(machine, step);
129-
});
130+
this.system.suspend(function() {
131+
function_scope.system.set_current(function_scope.pid);
132+
function_scope.run(machine, step);
133+
});
130134
}else{
131-
this.system.schedule(function() {
132-
function_scope.system.set_current(function_scope.pid);
133-
function_scope.run(machine, machine.next(result));
134-
});
135+
this.system.schedule(function() {
136+
function_scope.system.set_current(function_scope.pid);
137+
function_scope.run(machine, machine.next(result));
138+
});
135139
}
136140

137141
}else{
138-
this.system.schedule(function() {
139-
function_scope.system.set_current(function_scope.pid);
140-
function_scope.run(machine, machine.next(value));
141-
});
142+
this.system.schedule(function() {
143+
function_scope.system.set_current(function_scope.pid);
144+
function_scope.run(machine, machine.next(value));
145+
});
142146
}
143147
}
144148
}
145149
}
146150

147-
export default Process;
151+
export default Process;

0 commit comments

Comments
 (0)