Class: EditMediator::UpdateThread

Inherits:
Object
  • Object
show all
Defined in:
frontend/app/models/edit_mediator.rb

Constant Summary collapse

SYNC_WITH_BACKEND_SECONDS =

We send our local copy of the active edits table to the backend periodically. Set this the same as the client’s INTERVAL_PERIOD so we don’t add too much delay to a client’s update hitting the backend.

10

Instance Method Summary collapse

Constructor Details

#initialize(active_edits, queue) ⇒ UpdateThread

Returns a new instance of UpdateThread.



48
49
50
51
# File 'frontend/app/models/edit_mediator.rb', line 48

def initialize(active_edits, queue)
  @active_edits = active_edits
  @queue = queue
end

Instance Method Details

#log_in_to_backend(force = false) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'frontend/app/models/edit_mediator.rb', line 64

def (force = false)
  @backend_session = nil if force

  if !@backend_session
    response = JSONModel::HTTP.post_form("/users/#{AppConfig[:staff_username]}/login",
                                         {
                                           "expiring" => "false",
                                           "password" => AppConfig[:staff_user_secret]
                                         })

    auth = ASUtils.json_parse(response.body)

    @backend_session = auth['session']
  end

  @backend_session
end

#record_update_locally(user, uri, last_report_time) ⇒ Object



54
55
56
57
58
59
60
61
# File 'frontend/app/models/edit_mediator.rb', line 54

def record_update_locally(user, uri, last_report_time)
  @active_edits.update {|edits|
    entry = edits[uri] ? edits[uri].clone : {'edited_by' => {}}
    entry['edited_by'][user] = last_report_time

    edits.merge(uri => entry)
  }
end

#startObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'frontend/app/models/edit_mediator.rb', line 107

def start
  # The main thread: respond to updates and manage the local editing state.
  Thread.new do
    while true
      begin
        request = @queue.pop

        if request[:type] == :update
          self.record_update_locally(*request[:values])
        elsif request[:type] == :sync
          self.synchronise_with_backend
        end
      rescue
        $stderr.puts("ERROR: Edit mediator: #{$!}: #{$@}")
        sleep 5
      end
    end
  end


  # A separate thread to trigger a sync with the backend every now and then.
  Thread.new do
    while true
      sleep SYNC_WITH_BACKEND_SECONDS
      @queue << {:type => :sync}
    end
  end
end

#synchronise_with_backendObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'frontend/app/models/edit_mediator.rb', line 83

def synchronise_with_backend
  snapshot = @active_edits.value
  edits = JSONModel(:active_edits).new

  edits.active_edits = snapshot.map {|uri, entries|
    entries['edited_by'].map {|user, last_time|
      {
        'uri' => uri,
        'user' => user,
        'time' => last_time,
      }
    }
  }.flatten(1)

  JSONModel::HTTP.current_backend_session = 

  begin
    updated = edits.save({}, true)
    @active_edits.update {|old_val| updated}
  rescue AccessDeniedException
    (true)
  end
end