Skip to content

Instantly share code, notes, and snippets.

@mpahrens
Created July 12, 2015 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpahrens/4a87e01e54f5f00582d8 to your computer and use it in GitHub Desktop.
Save mpahrens/4a87e01e54f5f00582d8 to your computer and use it in GitHub Desktop.
Rundown of comms module to make new enchancement issues from for blockytalky_elixir
If you look at the latest develop. (July 11th) The files you can look at are:
blockytalky/lib/blockytalky/comm/comms_module.ex => the Blockytalky.CommsModule module
blockytalky/lib/blockytalky/lang/dsl.ex => the Blockytalky.DSL module
blockytalky/web/blockytalky/channels/comms_channel.ex => the Blockytalky.CommsChannel module
blockytalky/web/static/js/app.js => the client side code that reacts.
blockytalky/web/templates/view/index.html.eex => the client side html templates that turns into the main webpage. (also look at the other sub-templates that it renders. I made it fairly composable.)
Currently how sending messaging works is:
Kids right code that generates something like:
defmodule Blockytalky.UserCode do
use Blockytalky.DSL
when_receive "hello", do
...do work here...
end
end
Which gets turned into code that looks like this (see dsl.ex: defmacro when_receive)
GenServer.cast(Blockytalky.UserState. {:push_fun, :loop, fn ->
if("hello" = get(:sys_message)) do # where :sys_message is the last message dequeued from the message queue
....do work...
end
end
So then while the kid hits the "run" button, this code is compiled, adding the lambda function to the loop function stack, and then each time though the run loop, it runs this lamda.
So you can add two types of featurs here:
1) Stuff outside of the lambda, which executes at `compile time` (when the kid hit the run button)
2) Stuff inside the lambda, which executes at `runtime` everytime the kids' code loop runs.
And example of 1) is shoving the message that the kids code is listening for into a GenServer (the UserState server is the state server about all things kids code). And then when the btu announces itself locally, it puts this in the payload. Or it could do its own announcement for this kind of message.
To broadcast any information that changes serverside to the client. Look at any of the channele examples. To broadcast a message, you call:
Blockytalky.Endpoint.broadcast "channel_topic:subtopic", "action", payload
payload is typically a map. it can have any form, but the default one I have been using is %{"body"=>"message"}.
Note, tuples cannot be json-ized. So even though, in elixir, you can put a {:ok, whatever} or a [keyword: list] in a map, it will throw a runtime error when turned into json. lists [], strings, numbers, and other maps are completely fine.
Look at app.js to see how the different channels handle subscribing to different topics and acting on different "actions".
TL;DR version:
Add code to the dsl to stash the messages kids code reacts to into a genserver's state
somehow broadcast to all other BTUs what messages your btu reacts to, periodically
when receing a broadcast from another btu (comms module), tell the ui to update its info and pass it the information in a map
in the app.js , use a channel to receive btu message info from the broadcast and update the ui elements
in a new template that index.html.eex renders, handle displaying information app.js tells you to.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment