11module Operations
2- # encapsulates our "messages store" server side
3- # the params and dispatcher will be inherited
2+ # Operations can be inherited so we encapsulates our
3+ # "messages store" server side in the ServerBase class.
4+
5+ # ServerBase provides the common parameters,
6+ # two methods "messages" and "add_message",
7+ # and the common dispatch step.
8+
49 class ServerBase < Hyperloop ::ServerOp
10+ # for an Operation to be run remotely it must take
11+ # an acting_user param. However we will allow it to
12+ # be nil, thus no login is required.
13+ # In a real app we would use a validation step to insure
14+ # the acting_user had authorization to run the operation.
515 param :acting_user , nils : true
16+ # because this is a toy app we are also going to provide a simple
17+ # user name as a string normally this would be an attribute of the
18+ # acting user.
619 param :user_name
20+
21+ # the base behavior is simply to dispatch the parameters back to entire
22+ # application. Subclasses will add more data.
723 dispatch_to { Hyperloop ::Application }
824
25+ # we also provide a couple of methods that encapsulate the server side
26+ # persistance. In this case we just use the Rails cache.
927 def messages
1028 Rails . cache . fetch ( 'messages' ) { [ ] }
1129 end
1230
13- def add_message
31+ def add_message
32+ # add_message expects a message param to be present
33+ # this is done this way just to show how steps can be simple
34+ # method calls.
1435 params . message = {
1536 message : params . message ,
1637 time : Time . now ,
@@ -20,12 +41,21 @@ def add_message
2041 end
2142 end
2243
23- # get all the messages
44+ # We now build two runnable Operations
45+
46+ # GetMessages simply adds an "outbound" param called messages
47+ # which it will set.
2448 class GetMessages < ServerBase
2549 outbound :messages
2650
51+ # the only added step is to get the messages and place it in the
52+ # messages param which will be dispatched
2753 step { params . messages = messages }
2854
55+ # currently the deserializer (run on the client) does not
56+ # handle Time conversion properly due to the differences in the way
57+ # JS and Opal represent time. So we will add our own custom
58+ # deserializer.
2959 def self . deserialize_dispatch ( messages )
3060 # convert the time string back to time
3161 messages [ :messages ] . each do |message |
@@ -35,10 +65,12 @@ def self.deserialize_dispatch(messages)
3565 end
3666 end
3767
38- # send a message to everybody
68+ # The Send operation just sends a message to everybody.
69+ # We just add a param called message to the ServerBase
3970 class Send < ServerBase
4071 param :message
4172
73+ # the only step is simply to run add_message
4274 step :add_message
4375
4476 def self . deserialize_dispatch ( message )
@@ -49,6 +81,8 @@ def self.deserialize_dispatch(message)
4981 end
5082
5183 # client side only: registers user_name and then gets the messages
84+ # notice how steps can invoke other Operations. steps will automatically
85+ # deal with promises, chaining them together as necessary.
5286 class Join < Hyperloop ::Operation
5387 param :user_name
5488 step GetMessages
0 commit comments