Advertisement
Guest User

Untitled

a guest
May 19th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 4.59 KB | None | 0 0
  1. ========================================
  2. ============== Supervisor ==============
  3. ========================================
  4. ### This module controls the processes,
  5. ### `Sequence.Stash` is going to store the applications state
  6. ### `Sequence.Server` is going to perform the logic behind the application
  7.  
  8. defmodule Sequence.Application do
  9.   use Application
  10.  
  11.   def start(_type, _args) do
  12.     children = [
  13.       {Sequence.Stash, 123},
  14.       {Sequence.Server, nil}
  15.     ]
  16.  
  17.     opts = [strategy: :rest_for_one, name: Sequence.Supervisor]
  18.     Supervisor.start_link(children, opts)
  19.   end
  20. end
  21.  
  22.  
  23. =============================================
  24. ============== Sequence.Server ==============
  25. =============================================
  26. ### Our logic is performed in this module.
  27. ### You would run these commands through the shell using `Sequence.Server.next_number`
  28. ### Or `Sequence.Server.increment(int), this is where we could pass false data into throw an exception.
  29.  
  30. defmodule Sequence.Server do
  31.   use GenServer
  32.  
  33.  
  34.   ### This function starts the process
  35.   ### It uses `__MODULE__` to auto discover the module it is being called in
  36.   def start_link(_) do
  37.     GenServer.start_link(__MODULE__, nil, name: __MODULE__)
  38.   end
  39.  
  40.  
  41.   ### Function is called to make a request to one of the `handle_call` functions below,
  42.   ### This is matched by the second param that is supplied `:next_number`
  43.   def next_number do
  44.     GenServer.call(__MODULE__, :next_number)
  45.   end
  46.  
  47.   ### Adds ten to the number that is current in the application state
  48.   def next_ten do
  49.     GenServer.call(__MODULE__, :next_ten)
  50.   end
  51.  
  52.  
  53.   ### This module also does the same as above
  54.   ### Difference is it requires an integer to be provided to add the the state of the process
  55.   ### This is also the the function that we would use to create an exception by passing a string
  56.   def increment(delta) do
  57.     GenServer.cast(__MODULE__, {:increment_number, delta})
  58.   end
  59.  
  60.  
  61.   ### Function initializes the process, and similar to how you would a constructor in an OOP language
  62.   ### We use it to start our `Stash` process to store the state in the case of an exception
  63.   def init(_) do
  64.     {:ok, Sequence.Stash.get()}
  65.   end
  66.  
  67.  
  68.   ### These are our handlers, that are being called in the functions above, you use pattern matching
  69.   ### for the system to understand which one to use, it is matched by the first parameter.
  70.   def handle_call(:next_number, _from, current_number) do
  71.     {:reply, current_number, current_number + 1}
  72.   end
  73.  
  74.   ### Same as above, but instead adds ten to the state
  75.   def handle_call(:next_ten, _from, current_number) do
  76.     {:reply, current_number, current_number + 10}
  77.   end
  78.  
  79.  
  80.   ### This is similar to the `handle_call` functions, but does not return data to the user, simply stores it in the state
  81.   ### This is also a function that you would use with pattern matching the first parameter, ex. {:increment_number, delta}
  82.   def handle_cast({:increment_number, delta}, current_number) do
  83.     {:noreply, current_number + delta}
  84.   end
  85.  
  86.  
  87.   ### This function is used in case of an exception, it will store the `current_number` into the applications state
  88.   ### when an exception is called.
  89.   def terminate(_reason, current_number) do
  90.     Sequence.Stash.update(current_number)
  91.   end
  92.  
  93.  
  94.   ### This is simply used as formatting when you check the status of the state.
  95.   ### This can be called at anytime to check the status of the state.
  96.   def format_status(_reason, [_pdict, state]) do
  97.     [data: [{'State', "The current state is '#{inspect(state)}'"}]]
  98.   end
  99. end
  100.  
  101.  
  102. =============================================
  103. ============== Sequence.Stash ==============
  104. =============================================
  105. ### This module is used to initialize the state, you can see this in the `Sequence.Supervisor`, it is run first.
  106. ### The `Sequence.Server` calls the `get()` function here to get the initial value, which is set to `123` in the Supervisor.
  107. ### The `Update` function is called once the `Sequence.Server` module is terminated.
  108.  
  109. defmodule Sequence.Stash do
  110.   use GenServer
  111.  
  112.   @me __MODULE__
  113.  
  114.   def start_link(initial_number) do
  115.     GenServer.start_link(__MODULE__, initial_number, name: @me)
  116.   end
  117.  
  118.   def get() do
  119.     GenServer.call(@me, {:get})
  120.   end
  121.  
  122.   def update(new_number) do
  123.     GenServer.cast(@me, {:update, new_number})
  124.   end
  125.  
  126.   def init(initial_number) do
  127.     {:ok, initial_number}
  128.   end
  129.  
  130.   def handle_call({:get}, _from, current_number) do
  131.     {:reply, current_number, current_number}
  132.   end
  133.  
  134.   def handle_cast({:update, new_number}, _current_number) do
  135.     {:noreply, new_number}
  136.   end
  137. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement