Skip to content

Communication On FaceIn - This assignment is about how parts of FaceIn could be implemented in Erlang (see also the Prolog assignment about FaceIn).

Notifications You must be signed in to change notification settings

tudorgk/AP-Assignment4

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Communication On FaceIn - This assignment is about how parts of FaceIn could be implemented in Erlang (see also the Prolog assignment about FaceIn).

Implementation

####start(N) function

start(Person) -> spawn(fun () -> 
	loop(dict:store(messageRefs,[],
		 dict:store(messages,[],
		 dict:store(friend_list,[],
		 dict:store(name, Person, 
		 dict:new()))))) end).

The start function spawns a new process that stores a database represented by a dictionary. The loop function is a blocking function that waits for requests from other processes.

####add_friend(P,F) function

% add a pid (F) to a pid's (P) firend list
add_friend(P,F) ->
	F ! {self(), get_name},
	receive
		{F, {ok,Name}} -> 
			P ! {self(),{add_friend,{Name,F}}},
			receive
				{P, ok} -> "friend added";
				{P, {error,Reason2}} -> Reason2
			end;
		{F, {error,Reason1}} -> Reason1
	end.

The add_friend function gets the name of the F process to store it into the friend list. After it receives the response, it send a request to process P to add the name and PID to the freind list.

####broadcast(P, M, R) function

%broadcast a message (M) to all of (P) friends within radius (R)
broadcast(P, M, R) ->
	MessageRef = make_ref(),
	{ok, Name} = name(P),
	rpc_no_response(P, {broadcast_msg, {Name,MessageRef, M, R}}).

The broadcast function creates a distinct message reference and passes to every connected friend, which in turn pass the message along until the radius R is 0.

###Request handling

The get_friends, add_friends are pretty straight forward, the first one gets the friend list from the dictionary, and the second one add a friend to the friend list. The database is updated by creating a new dictionary from the old one and recursively calling loop with the new dictionary.

The most important part is probably the brodcast_msg request. Every process receives a package with the process that sent the message, the message reference so that we don't add duplicates to the message list, the actual message string, and the TTL represented by the radius R.

We check that the radius R is greater than 0. If it is, we pass the message on by submiting a request to all the friends from the process who received the message.

case R > 0 of
				true -> 	
					%send to friends with (R-1)
					{ok, FriendList} = dict:find(friend_list, PersonDatabase),
					lists:map(fun({FriendName,Pid}) -> Pid ! {self(), {broadcast_msg, {P,MessageRef, M, R-1}}}  end, FriendList),
					true;

				false -> false
				%stop sending
			end,

After that we check if the message is already in the list. If it's not, we append the message to the message list and keep the reference in a separate list.

case lists:member(MessageRef,MessageRefList) of
				false ->
					NewMessageListRef = [MessageRef | MessageRefList],
					{ok, MessageList} = dict:find(messages, PersonDatabase),
					NewMessageList = [{P,M} | MessageList],
					loop(dict:store(messageRefs,NewMessageListRef,
						 dict:store(messages, NewMessageList, PersonDatabase)));
				true ->
					loop(PersonDatabase)
			end;

Testing

###Usage:

####1. Compile using make

user:shell$ make test

####2. Run the tests

1> tester:test().

About

Communication On FaceIn - This assignment is about how parts of FaceIn could be implemented in Erlang (see also the Prolog assignment about FaceIn).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages