Created
July 11, 2020 00:33
-
-
Save tecnowilliam/ee50692d8a715ee8867ef65d78ee36b4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| % Compile: c(frequency). | |
| -module(frequency). | |
| -author("William Vargas"). | |
| -version("1.0"). | |
| -export([init/2, start/2]). | |
| % Register the server as frequency_hardened | |
| -spec start(atom(), list(integer())) -> pid(). | |
| start(Process, Frequencies) -> | |
| register(Process, spawn_link(?MODULE, init, [Process, Frequencies])). | |
| % Initialize the server | |
| -spec init(atom(), list(integer())) -> any(). | |
| init(Process, Frequencies) -> | |
| process_flag(trap_exit, true), | |
| io:format("~w started: ~w~n", [Process, whereis(Process)]), | |
| loop(Process, Frequencies). | |
| %% The Main Loop | |
| loop(Process, Frequencies) -> | |
| receive | |
| {request, Pid, allocate} -> | |
| {NewFrequencies, Reply} = allocate(Frequencies, Pid), | |
| Pid ! {reply, Reply}, | |
| io:format("~w - allocate: ~w~n", [Process, NewFrequencies]), | |
| loop(Process, NewFrequencies); | |
| {request, Pid , {deallocate, Freq}} -> | |
| {NewFrequencies, Reply} = deallocate(Frequencies, Freq), | |
| Pid ! {reply, Reply}, | |
| io:format("~w - deallocate ~w: ~w~n", [Process, Freq, NewFrequencies]), | |
| loop(Process, NewFrequencies); | |
| {request, Pid, frequencies} -> | |
| io:format("~w - frequencies: ~w~n", [Process, Frequencies]), | |
| Pid ! {reply, {ok, Frequencies}}; | |
| {request, Pid, stop} -> | |
| Pid ! {reply, {ok, stopped}} | |
| end. | |
| % Allocate a frequency | |
| -spec allocate(list(), pid()) -> tuple(). | |
| allocate({[], Allocated}, _Pid) -> | |
| {{[], Allocated}, {error, no_frequency}}; | |
| allocate({[Freq|Free], Allocated}, Pid) -> | |
| {{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}. | |
| % Deallocate a frequency | |
| -spec deallocate(tuple(), integer()) -> tuple(). | |
| deallocate({Free, Allocated}, Freq) -> | |
| case lists:keyfind(Freq, 1, Allocated) of | |
| {Freq, Pid} -> | |
| NewAllocated = lists:delete({Freq, Pid}, Allocated), | |
| {{[Freq|Free], NewAllocated}, {ok, Freq}}; | |
| _ -> | |
| {{Free, Allocated}, {error, no_frequency}} | |
| end. |
This file contains hidden or 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
| % Compile: c(router). | |
| -module(router). | |
| -author("William Vargas"). | |
| -version("1.0"). | |
| -export([start/0, stop/1, allocate/0, deallocate/1, tests/0]). | |
| % Launch the processes | |
| -spec start() -> any(). | |
| start() -> | |
| frequency:start(freq1, {[1,2,3,4,5,6,7,8,9,10],[]}), | |
| frequency:start(freq2, {[11,12,13,14,15,16,17,18,19,20],[]}), | |
| frequency:start(freq3, {[21,22,23,24,25,26,27,28,29,30],[]}). | |
| % Stop a process | |
| -spec stop(atom()) -> any(). | |
| stop(Process) -> | |
| Process ! {request, self(), stop}, | |
| io:format("~w stopped: ~w~n", [Process, whereis(Process)]). | |
| % Allocate a frequency | |
| -spec allocate() -> any(). | |
| allocate() -> | |
| case rand:uniform(3) of | |
| 1 -> allocate(freq1); | |
| 2 -> allocate(freq2); | |
| _ -> allocate(freq3) | |
| end. | |
| -spec allocate(atom()) -> any(). | |
| allocate(Process) -> | |
| case is_pid(whereis(Process)) of | |
| true -> | |
| Process ! {request, self(), allocate}, | |
| receive | |
| {reply, Reply} -> | |
| Reply; | |
| _ -> | |
| {error, invalid_reply} | |
| after 1000 -> | |
| clear() | |
| end; | |
| _ -> | |
| allocate() | |
| end. | |
| % Deallocate a frequency | |
| -spec deallocate(integer()) -> any(). | |
| deallocate(Freq) -> | |
| case Freq =< 10 of | |
| true -> | |
| deallocate(freq1, Freq); | |
| _ -> | |
| case Freq =< 20 of | |
| true -> | |
| deallocate(freq2, Freq); | |
| _ -> | |
| deallocate(freq3, Freq) | |
| end | |
| end. | |
| deallocate(Process, Freq) -> | |
| Process ! {request, self(), {deallocate, Freq}}, | |
| receive | |
| {reply, Reply} -> | |
| Reply; | |
| _ -> | |
| {error, invalid_reply} | |
| after 1000 -> | |
| clear() | |
| end. | |
| % Clear the mailbox | |
| -spec clear() -> ok. | |
| clear() -> | |
| receive | |
| _Msg -> clear() | |
| after 0 -> | |
| io:format("Mailbox cleared~n") | |
| end. | |
| % Tests | |
| % Compile before run the tests | |
| % c(frequency). | |
| % c(router). | |
| -spec tests() -> any(). | |
| tests() -> | |
| start(), | |
| allocate(), | |
| allocate(), | |
| allocate(), | |
| allocate(), | |
| allocate(), | |
| deallocate(1), | |
| deallocate(11), | |
| deallocate(21), | |
| stop(freq1), | |
| allocate(), | |
| allocate(), | |
| allocate(). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment