-
Notifications
You must be signed in to change notification settings - Fork 0
/
Elixir implementation research.txt
56 lines (38 loc) · 2.96 KB
/
Elixir implementation research.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
NIF (Native Implemented Function)
- can implement existing C functions in Elixir (maybe Rust can be used?)
* NB: a failure in the C function will bring down the entire VM
:resources
- "a safe way to return pointers to native data structures from a NIF. A resource object is just a block of memory"
:oberver.start
- observe BEAM state in iex
** distillery **
- send lookup message with original requesting node
* initialisation decisions *
- bit size will be set when starting up a node as bit size knowledge is a-priori in the network
- defaiult stabilization interval is 30 seconds [chord-sectn. 6.5]
- With Node ID, use {nodeName@IPAddress} as some nodes might have the same address. In the case of them being class c addresses
- Keys can be stored in list as list size wont be that big. Lookup should be worst O(2^m)
* inter-node communication *
- options:
- gRPC
- JSON-RPC
- can use JSON-RPC TCP to detect when connections go down
- using HTTP(S) means connections don't have to remain open as number of open connections can scale to size m where m is bit-size
- why RPC over REST?
- REST exposes data as resources to be acted upon, whereas RPC exposes operations as a method for acting upon data [nodricapis]
- using JSON-RPC as Elixir gRPC libraries are not yet that mature
- Store kV data in ETS
- ETS offers constant time access compared to Maps which are O(log N)
*** challenges faced ***
- finger table can't be implemented as list as Elixir lists are linked lists under the hood. Meaning a sparse list can't be generated. Instead a map has been used where an existing key check can be done
- Linking a transport server to a node. How does transport pass request to appropriate node
- maybe use Agent to map server -> node
- Due to difficulty mapping an individual transport process to a node, A physical machine will have one transport process shared amongst 1-* node processes. The issue was a limitation in the JSONRPC2 library in that it doesn't have an option to pass some initial state to the server process.
- GenServer calls will have to be non-blocking. So use GenServer.cast as a request waiting on other remote calls will block other incoming ones
- There is no explicit support for interfaces so dynamic module imports have to be used. e.g. in transport layer
*** points of improvement ***
- maybe use an agent to store node state instead of local state. In case a node process crashes, state won't be lost. (let it crash philosophy). although...bad state might be the reason for the crash...
- separate key management from node logic. So that node crashes don't lead to loss of data (making let it crash easier). The only downside will be loss of stable finger table entries.
*** testing ***
- performance might not be as good as figures in paper as I have not implemented the 'successor list' modification
- secondly, network might not be in a completely stable state. Which is mentioned in the paper that practically, the network might not be completely stable