aboutsummaryrefslogtreecommitdiffstats
path: root/etherpad/src/etherpad/pro/pro_pad_editors.js
blob: a90f05b30b1b5275f0a377deea69bdca7d0d92cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import("execution");
import("jsutils.*");
import("cache_utils.syncedWithCache");

import("etherpad.pad.padutils");
import("etherpad.pro.pro_padmeta");
import("etherpad.log");

var _DOMAIN_EDIT_WRITE_INTERVAL = 2000; // 2 seconds

function _withCache(name, fn) {
  return syncedWithCache('pro-padmeta.'+name, fn);
}

function _withDomainCache(domainId, name, fn) {
  return _withCache(name+"."+domainId, fn);
}


function onStartup() {
  execution.initTaskThreadPool("pro-padmeta-edits", 1);
}

function onShutdown() {
  var success = execution.shutdownAndWaitOnTaskThreadPool("pro-padmeta-edits", 4000);
  if (!success) {
    log.warn("Warning: pro.padmeta failed to flush pad edits on shutdown.");
  }
}

function notifyEdit(domainId, localPadId, editorId, editTime) {
  if (!editorId) {
    // guest editors
    return;
  }
  _withDomainCache(domainId, "edits", function(c) {
    if (!c[localPadId]) {
      c[localPadId] = {
        lastEditorId: editorId,
        lastEditTime: editTime,
        recentEditors: []
      };
    }
    var info = c[localPadId];
    if (info.recentEditors.indexOf(editorId) < 0) {
      info.recentEditors.push(editorId);
    }
  });
  _flushPadEditsEventually(domainId);
}


function _flushPadEditsEventually(domainId) {
  // Make sure there is a recurring edit-writer for this domain
  _withDomainCache(domainId, "recurring-edit-writers", function(c) {
    if (!c[domainId]) {
      flushEditsNow(domainId);
      c[domainId] = true;
    }
  });
}

function flushEditsNow(domainId) {
  if (!appjet.cache.shutdownHandlerIsRunning) {
    execution.scheduleTask("pro-padmeta-edits", "proPadmetaFlushEdits",
                            _DOMAIN_EDIT_WRITE_INTERVAL, [domainId]);
  }

  _withDomainCache(domainId, "edits", function(edits) {
    var padIdList = keys(edits);
    padIdList.forEach(function(localPadId) {
      _writePadEditsToDbNow(domainId, localPadId, edits[localPadId]);
      delete edits[localPadId];
    });
  });
}

function _writePadEditsToDbNow(domainId, localPadId, editInfo) {
  var globalPadId = padutils.makeGlobalId(domainId, localPadId);
  pro_padmeta.accessProPad(globalPadId, function(propad) {
    propad.setLastEditedDate(editInfo.lastEditTime);
    propad.setLastEditor(editInfo.lastEditorId);
    editInfo.recentEditors.forEach(function(eid) {
      propad.addEditor(eid);
    });
  });
}