Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronous editing documentation #933

Open
wants to merge 2 commits into
base: synch-editing-tests
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions SYNCHRONOUS_EDITING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
The new synchronous editing feature
===================================

With the introduction of ActionCable to our system, it has been possible
to do perform real-time tasks quite easily. We have used rail's default
action cable to make a _concurrent_editing_channel.rb_ in the _app/channels_ folder,
to handle all the incoming requests and consists of all the business
logic as well. At the frontend we have, _app/javascripts/channels/concurrent_editing.js_ which
handles the logic at the browser or the frontend.

## Flow of the feature:

1. When the map is updated, the _speak_ method of _concurrent_editing.js_ is called which requests
the _sync_ method of _concurrent_editing_channel.rb_ to broadcast the updated data to
the connected users.

2. The broadcasted data is finally caught by the _received_ function of _app/javascripts/channels/concurrent_editing.js_

3. Finally the _received_ function calls the _synchronizeData_ function to update
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similary finally should be changed or removed

all the fresh data on the map.


## Testing:

1. The _action-cable-testing_ gem is used for the feature's testing. It has some really
cool testing functionality which was required for our use case.

2. Currently we have separate tests written for connection related features and channel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation should not have words like currently as in future, it will give false negative impressions.
Try to read the document from the view of newbie of MK after 2 years of publishing this doc. Documents are least maintained so we need to be extra careful.

specific features. The relevant files are test/channels/concurrent_editing_channel_test.rb and
test/channels/connection_test.rb
8 changes: 6 additions & 2 deletions app/assets/javascripts/channels/concurrent_editing.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* Handles all the frontend interactions with action cable and the server. */

App.concurrent_editing = App.cable.subscriptions.create("ConcurrentEditingChannel", {
connected: function() {
// Called when the subscription is ready for use on the server
console.log("Connected");
},

disconnected: function() {
// Called when the subscription has been terminated by the server
console.log("bye");
},

received: function(data) {
Expand All @@ -15,6 +15,10 @@ App.concurrent_editing = App.cable.subscriptions.create("ConcurrentEditingChanne
},

speak: function(changes) {
/* Called when an image is updated from Map.js ('saveImage' function).
* This function calls concurrent_editing_channel.rb's 'sync' method
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't write This.
Reason a new developer writes comments between 18 and 19 LOC then this will become outdated and ambiguous.

* which is responsible for broadcasting the updated warpables
* to all the user's connected to the concurrent_editing channel. */
return this.perform("sync", {
changes: changes
});
Expand Down
3 changes: 3 additions & 0 deletions app/assets/javascripts/mapknitter/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ MapKnitter.Map = MapKnitter.Class.extend({
if (this.editing._mode !== "lock") { e.stopPropagation(); }
},

/* Called by the concurrent_editing.js channel's 'received' function (app/assets/javascripts/channels/concurrent_editing.js).
* It recieves a list of updated warpables,i.e. list of images with updated corner points. The aim of writing this function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Write name of function instead of pronouns. Change `It'

* is to reposition the updated images onto the map on every connected browser (via the ActionCable). */
synchronizeData: function(warpables) {
var layers = [];
map.eachLayer(function(l) {layers.push(l)});
Expand Down
4 changes: 4 additions & 0 deletions app/channels/concurrent_editing_channel.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
class ConcurrentEditingChannel < ApplicationCable::Channel
# This class handles the server side logic of the actioncable communication.

def subscribed
# Called first to connect user to the channel.
stream_from "concurrent_editing_channel"
end

Expand All @@ -8,6 +11,7 @@ def unsubscribed
end

def sync(changes)
# Responsible for broadcasting the updated warpables or simply images to the user's connected on this channel.
ActionCable.server.broadcast 'concurrent_editing_channel', changes
end
end
2 changes: 1 addition & 1 deletion app/controllers/images_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def update
@warpable.locked = params[:locked]
@warpable.cm_per_pixel = @warpable.get_cm_per_pixel
@warpable.save
data = @warpable.map.fetch_map_data
data = @warpable.map.fetch_map_data # Get the updated warpable data
render json: data
render html: 'success'
else
Expand Down
1 change: 1 addition & 0 deletions app/models/map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ def add_tag(tagname, user)
end

def fetch_map_data
# fetches a list of updated warpables along with their corners in a json format.
data = warpables
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uppercase F in fetches

data.to_json
end
Expand Down