seapig-rails 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25b28f9d7975a6bfd32062f20bc310c01d79735e
4
- data.tar.gz: 186a43d3f1e36b1b8b1244d6524b344388d34e74
3
+ metadata.gz: 02ffc579c05bd9348fb6951b13c49e2dd59fd9de
4
+ data.tar.gz: 4085bb327476405fdc3f9d219fffa8c5fbece221
5
5
  SHA512:
6
- metadata.gz: 31bd90e20f73825d39bcafd121eaf070a0f35229bfd2d574ca63ae96ed1b00d7b5e33343622acae53dd5c28c9ed02cad3e7d6895ac720cdc660f5dab254d9d7d
7
- data.tar.gz: ce55ecb9cfe3acfcb52b8d24992b2ed4b037f15700d6da06590e602b1352754a12ffaf94f9d249b6747c60b14b93de8d8734cffeada736ad30e5abf58363ac57
6
+ metadata.gz: 891935bfbb159d2c385790a4bcb04720c3e0d71ac644c09620619a0dcdef82254c6b0fbf68ca5c42590b3a326e4fd7e44c98dfbf3c28444be1afe6a1c3fa7375
7
+ data.tar.gz: 3df6423bed314b75e7c549a095955ffe511dfbee16d5f7da781c74b219849ee83088dc2e5a5790cafca44c8172392524d99a7b978afb2f11fc5256e30a353664
@@ -30,6 +30,9 @@ class @SeapigServer
30
30
  @socket.send(JSON.stringify(action: 'client-options-set', options: @options))
31
31
  for object_id, object of @slave_objects
32
32
  @socket.send(JSON.stringify(action: 'object-consumer-register', id: object_id, latest_known_version: object.version))
33
+ for object_id, object of @master_objects
34
+ @socket.send(JSON.stringify(action: 'object-producer-register', pattern: object_id))
35
+ object.upload(0,{})
33
36
 
34
37
  @socket.onmessage = (event) =>
35
38
  #console.log('Seapig message received', event)
@@ -37,45 +40,71 @@ class @SeapigServer
37
40
  switch data.action
38
41
  when 'object-update'
39
42
  @slave_objects[data.id].patch(data) if @slave_objects[data.id]
43
+ when 'object-produce'
44
+ @master_objects[data.id].upload(0,{}) if @master_objects[data.id]
40
45
  else
41
46
  console.log('Seapig received a stupid message', data)
42
47
 
43
48
 
44
49
  slave: (object_id) ->
45
- @socket.send(JSON.stringify(action: 'object-consumer-register', id: object_id, latest_known_version: null)) if @connected
46
- @slave_objects[object_id] = new SeapigObject(object_id)
50
+ @socket.send(JSON.stringify(action: 'object-consumer-register', id: object_id, latest_known_version: 0)) if @connected
51
+ @slave_objects[object_id] = new SeapigObject(@,object_id)
47
52
 
48
53
 
49
- unlink: (object_id) ->
50
- delete @slave_objects[object_id]
51
- @socket.send(JSON.stringify(action: 'unlink', id: object_id)) if @connected
54
+ master: (object_id) ->
55
+ @socket.send(JSON.stringify(action: 'object-producer-register', pattern: object_id)) if @connected
56
+ @master_objects[object_id] = new SeapigObject(@,object_id)
52
57
 
53
58
 
59
+ unlink: (object_id)->
60
+ if @slave_objects[object_id]?
61
+ delete @slave_objects[object_id]
62
+ @socket.send(JSON.stringify(action: 'object-consumer-unregister', id: object_id)) if @connected
63
+ if @master_objects[object_id]?
64
+ delete @master_objects[object_id]
65
+ @socket.send(JSON.stringify(action: 'object-producer-unregister', id: object_id)) if @connected
66
+
54
67
 
55
68
  class SeapigObject
56
69
 
57
70
 
58
- constructor: (id) ->
71
+ constructor: (server,id) ->
72
+ @server = server
59
73
  @id = id
60
74
  @valid = false
61
- @version = null
75
+ @version = 0
62
76
  @object = {}
63
77
  @shadow = {}
64
78
  @onchange = null
65
79
 
66
80
 
67
81
  patch: (data) ->
68
- if not data.old_version?
82
+ if data.old_version == 0
69
83
  delete @object[key] for key, value of @object
70
84
  else if not _.isEqual(@version, data.old_version)
71
- console.log("Seapig lost some updates, this shouldn't ever happen", @version, data.old_version)
85
+ console.log("Seapig lost some updates, this shouldn't ever happen. object:",@id," version:", @version, " old_version:", data.old_version)
72
86
  jsonpatch.apply(@object, data.patch)
73
87
  @version = data.new_version
74
88
  @valid = true
75
89
  @onchange() if @onchange?
76
90
 
77
91
  changed: () ->
92
+ old_version = @version
78
93
  @version += 1
79
- patch = jsonpatch.compare(@shadow, @object)
80
- console.log(patch)
94
+ @upload(old_version, @shadow)
81
95
  @shadow = JSON.parse(JSON.stringify(@object))
96
+
97
+
98
+ upload: (old_version, old_object)->
99
+ message = {
100
+ id: @id
101
+ action: 'object-patch'
102
+ old_version: old_version
103
+ new_version: @version
104
+ patch: jsonpatch.compare(old_object, @object)
105
+ }
106
+ @server.socket.send(JSON.stringify(message)) if @server.connected
107
+
108
+
109
+ unlink: () ->
110
+ @server.unlink(@id)
@@ -0,0 +1,104 @@
1
+ class @SeapigRouter
2
+
3
+
4
+ constructor: (seapig_server, session_id, initial_state, debug = false)->
5
+ @seapig_server = seapig_server
6
+ @session_id = session_id
7
+ @debug = debug
8
+
9
+ @state = _.extend({session_id: @session_id, id: 0}, initial_state)
10
+
11
+ @session_data = @seapig_server.master('web-session-data-'+@session_id)
12
+ @session_data.object.states = [ @state ]
13
+ @session_data.sequence = 1
14
+ @session_data.changed()
15
+
16
+ @session_data_saved = @seapig_server.slave('web-session-saved-'+@session_id)
17
+ @session_data_saved.onchange = ()=>
18
+ while @session_data.object.states[0]? and @session_data.object.states[0].id < @session_data_saved.object.max_state_id
19
+ @session_data.object.states.shift()
20
+ @replacing_state = true
21
+ window.history.replaceState(@state,null,@current_url())
22
+ @replacing_state = false
23
+
24
+
25
+ @replacing_state = false
26
+ @state_valid = false
27
+
28
+ $(document).on('click','a', (event) =>
29
+ console.log('ROUTER: A-element clicked, changing location to:', event.target.href) if @debug
30
+ return true if not event.target.href[0] == '?'
31
+ window.history.pushState(null,null,event.target.href)
32
+ @location_changed()
33
+ false
34
+ )
35
+
36
+ window.onpopstate = (data) =>
37
+ @state = data.state
38
+ @state_changed()
39
+
40
+
41
+
42
+ location_changed: () ->
43
+ return if @replacing_state
44
+ console.log('ROUTER: Location changed to: pathname:', window.location.pathname, ' search:', window.location.search) if @debug
45
+
46
+ spl = window.location.pathname.split('/')
47
+ if spl[1] == 'a'
48
+ path_session_id = spl[2]
49
+ path_state_id = spl[3]
50
+ else
51
+ path_session_id = @session_id
52
+ path_state_id = 0
53
+
54
+ overlay = {}
55
+ if window.location.search.length > 0
56
+ for pair in window.location.search.split('?')[1].split('&')
57
+ spl = pair.split('=',2)
58
+ overlay[spl[0]] = spl[1]
59
+
60
+ if path_session_id == @session_id
61
+ @state_change(overlay)
62
+ else
63
+ if @remote_state?
64
+ @state_change_to_remote(overlay)
65
+ else
66
+ @state_valid = false
67
+ @remote_state = @seapig_server.slave('web-session-state-'+path_session_id+':'+path_state_id)
68
+ @remote_state.onchange = ()=> @state_change_to_remote(overlay)
69
+
70
+
71
+ state_change_to_remote: (overlay) ->
72
+ @state = _.clone(@remote_state.object)
73
+ if _.size(overlay) > 0
74
+ @state_change(overlay)
75
+ else
76
+ @state_valid = true
77
+ @state_changed()
78
+
79
+
80
+ state_change: (overlay) ->
81
+ @state = _.extend(_.clone(@state), overlay)
82
+ @statefilter(@state) if @statefilter?
83
+ @state.session_id = @session_id
84
+ @state.id = @session_data.sequence++
85
+ @session_data.object.states.push(@state)
86
+ @session_data.changed()
87
+ if @remote_state?
88
+ @remote_state.unlink()
89
+ @remote_state = null
90
+ @state_valid = true
91
+ @state_changed()
92
+
93
+
94
+ current_url: ()->
95
+ '/a/'+@state.session_id+'/'+@state.id+(if (@session_data_saved.object.max_state_id >= @state.id or @state.session_id != @session_id) then '' else '#NOT-SHAREABLE')
96
+
97
+ state_changed: () ->
98
+
99
+ console.log("ROUTER: State changed to: state:", @state, ' url:', @current_url()) if @debug
100
+ @replacing_state = true
101
+ window.history.replaceState(@state,null,@current_url())
102
+ @replacing_state = false
103
+
104
+ @onstatechange(@state) if @onstatechange?
@@ -0,0 +1,19 @@
1
+ class SeapigRouterSession < ActiveRecord::Base
2
+
3
+ has_many :seapig_router_session_states
4
+
5
+ acts_as_seapig_dependency
6
+
7
+
8
+ def self.generate
9
+ session = SeapigRouterSession.new
10
+ begin
11
+ session.key = (('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a).shuffle[0..10].join('')
12
+ session.save!
13
+ rescue ActiveRecord::RecordNotUnique
14
+ retry
15
+ end
16
+ session
17
+ end
18
+
19
+ end
@@ -0,0 +1,7 @@
1
+ class SeapigRouterSessionState < ActiveRecord::Base
2
+
3
+ belongs_to :seapig_router_session
4
+
5
+ acts_as_seapig_dependency
6
+
7
+ end
@@ -0,0 +1,30 @@
1
+ #!/bin/env ruby
2
+
3
+ require './config/environment.rb'
4
+
5
+ require 'seapig-client'
6
+
7
+
8
+
9
+ EM.run {
10
+
11
+ SeapigServer.new(ARGV[0],name: 'session-saver').slave('web-session-data-*').onchange { |sessions|
12
+ sessions.each_pair { |session_key, session_data|
13
+ p session_key
14
+ session = SeapigRouterSession.find_by(key: session_key.split('-',4)[3])
15
+ max_state = session.seapig_router_session_states.order("state_id DESC").first
16
+ max_state_id = (max_state and max_state.state_id or -1)
17
+ session_data['states'].each { |state|
18
+ if state['id'] > max_state_id
19
+ puts Time.new.to_s + " " + state.inspect
20
+ SeapigRouterSessionState.create!(seapig_router_session_id: session.id, state_id: state['id'], state: state)
21
+ end
22
+ }
23
+ }
24
+ SeapigRouterSession.seapig_dependency_changed("SeapigRouterSessionState")
25
+ }
26
+
27
+ }
28
+
29
+
30
+
@@ -0,0 +1,9 @@
1
+ class CreateSeapigRouterSessions < ActiveRecord::Migration
2
+ def change
3
+ create_table :seapig_router_sessions do |t|
4
+ t.text :key
5
+ t.timestamps null: false
6
+ end
7
+ add_index :seapig_router_sessions, :key, unique: true
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class CreateSeapigRouterSessionStates < ActiveRecord::Migration
2
+ def change
3
+ create_table :seapig_router_session_states do |t|
4
+ t.integer :seapig_router_session_id
5
+ t.integer :state_id
6
+ t.jsonb :state
7
+
8
+ t.timestamps null: false
9
+ end
10
+ add_index :seapig_router_session_states, [:seapig_router_session_id,:state_id], unique: true, name: "seapig_router_session_states_index_1"
11
+
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Seapig
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,22 @@
1
+ require './config/environment.rb'
2
+
3
+ class SeapigRouterSessionSaved < Producer
4
+
5
+ @patterns = [ 'web-session-saved-*' ]
6
+
7
+
8
+ def self.produce(object_id)
9
+ object_id =~ /web-session-saved-([^-]+)/
10
+ session_key = $1
11
+ version = {
12
+ SeapigRouterSessionState: SeapigRouterSessionState.seapig_dependency_version
13
+ }
14
+ session = SeapigRouterSession.find_by(key: session_key)
15
+ max_state = session.seapig_router_session_states.order("state_id DESC").first
16
+ data = {
17
+ max_state_id: (max_state and max_state.state_id or -1)
18
+ }
19
+ [data, version]
20
+ end
21
+
22
+ end
@@ -0,0 +1,20 @@
1
+ require './config/environment.rb'
2
+
3
+ class SeapigRouterSessionStateProducer < Producer
4
+
5
+ @patterns = [ 'web-session-state-*' ]
6
+
7
+
8
+ def self.produce(object_id)
9
+ object_id =~ /web-session-state-([^-]+)\:(\d+)/
10
+ session_key = $1
11
+ state_id = $2.to_i
12
+ version = Time.new.to_f
13
+ p session_key, object_id
14
+ session = SeapigRouterSession.find_by(key: session_key)
15
+ data = SeapigRouterSessionState.find_by(seapig_router_session_id: session.id, state_id: state_id).state
16
+ p data
17
+ [data, version]
18
+ end
19
+
20
+ end
@@ -3,7 +3,7 @@ require File.expand_path('../boot', __FILE__)
3
3
  require 'rails/all'
4
4
 
5
5
  Bundler.require(*Rails.groups)
6
- require "seapig-rails"
6
+ require "seapig"
7
7
 
8
8
  module Dummy
9
9
  class Application < Rails::Application
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seapig-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - yunta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-21 00:00:00.000000000 Z
11
+ date: 2016-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -71,19 +71,28 @@ email:
71
71
  - maciej.blomberg@mikoton.com
72
72
  executables:
73
73
  - seapig-notifier
74
+ - seapig-session-saver
74
75
  extensions: []
75
76
  extra_rdoc_files: []
76
77
  files:
77
78
  - MIT-LICENSE
78
79
  - README.rdoc
79
80
  - Rakefile
80
- - app/assets/javascripts/seapig/seapig.js.coffee
81
+ - app/assets/javascripts/seapig/seapig-client.js.coffee
82
+ - app/assets/javascripts/seapig/seapig-router.js.coffee
83
+ - app/models/seapig_router_session.rb
84
+ - app/models/seapig_router_session_state.rb
81
85
  - bin/seapig-notifier
86
+ - bin/seapig-session-saver
82
87
  - config/routes.rb
88
+ - db/migrate/20151221110834_create_seapig_router_sessions.rb
89
+ - db/migrate/20151221111628_create_seapig_router_session_states.rb
83
90
  - lib/seapig-rails.rb
84
91
  - lib/seapig/acts_as_seapig_dependency.rb
85
92
  - lib/seapig/engine.rb
86
93
  - lib/seapig/version.rb
94
+ - lib/seapigs/seapig_router_saved_session.rb
95
+ - lib/seapigs/seapig_router_session_state.rb
87
96
  - lib/tasks/seapig_tasks.rake
88
97
  - test/dummy/README.rdoc
89
98
  - test/dummy/Rakefile