我必须在更改时将文件与firebase同步。我知道如何在文件更改时设置处理程序,然后调用Firebase.set
。但是如果文件很大(9mb)会发生什么,例如set
操作需要30秒才能完成,同时文件再次更改?当某些位置上的设置正在进行中并且在同一位置上执行第二次设置时会发生什么?
样本测试
ref1 = new Firebase('https://my_firebase.firebaseio.com/some_location')
ref2 = new Firebase('https://my_firebase.firebaseio.com/some_location')
ref1.set({ some_large_data: 'abcef...' });
ref2.set({ some_large_data: '12345...' });
// which set will take effect on server? second? Or random (second that actually completes)?
答案 0 :(得分:1)
如果我理解正确,你的问题就是这个问题:
Firebase的服务器将以事务方式处理更新,因此不会发生部分更新。
(完全)到达Firebase服务器的最后一次更新是将在节点中结束的更新。
如果您想要控制此类并发访问,那么您最好使用工作队列。当然,Firebase非常适合同步对这种工作队列的访问。 : - )
因此,在上面的流程中,在步骤3之后,服务器上不会写入您的Firebase节点。在第4步之后,Firebase将写入巨大的文件并且忘记了#34;来自客户端B的较小文件曾经存在过。如果您想防止这种意外覆盖,您可以考虑步骤0为"客户端使用transaction
呼叫锁定上传位置"。这基本上可以在Firebase的乐观锁定方法之上实现悲观锁定。
答案 1 :(得分:0)
所以在测试之后,似乎 Firebase将依次对服务器顺序执行所有set
操作,即使在上一次远程完成之前完成下一个操作,也不会取消任何操作
这意味着如果您调用set()
100次,则每个设置操作都会影响远程数据(数据库)。对于我的用例,这很糟糕,因为在每次更改文件时,它都会完全上传到firebase。我将不得不编写自己的算法来决定何时与firebase同步数据。
测试由两个脚本组成 - 一个是多次将数据写入同一个firebase位置,另一个是从该位置读取数据。
set_data.coffee
Firebase = require 'firebase'
firebaseUrl = 'https://my_firebase.firebaseio.com/same_location'
ref1 = new Firebase firebaseUrl
ref2 = new Firebase firebaseUrl
ref3 = new Firebase firebaseUrl
ref1.on 'value', (snapshot) -> console.log 'local same_location changed to ' + Buffer.byteLength((snapshot.val() or ''), 'utf8') + ' bytes'
data1 = ''
data2 = ''
data3 = ''
data1 += '1' for i in [1..1000*1000*2]
data2 += '2' for i in [1..1000*1000*3]
data3 += '3' for i in [1..100]
console.log 'data1 ' + Buffer.byteLength(data1, 'utf8') + ' bytes'
console.log 'data2 ' + Buffer.byteLength(data2, 'utf8') + ' bytes'
console.log 'data3 ' + Buffer.byteLength(data3, 'utf8') + ' bytes'
t1 = new Date()
ref1.set data1, (err) ->
elapsed = new Date().getTime() - t1.getTime()
console.log 'set1 finished ('+elapsed+'ms) - err is '+err
t2 = new Date()
ref2.set data2, (err) ->
elapsed = new Date().getTime() - t2.getTime()
console.log 'set2 finished ('+elapsed+'ms) - err is '+err
t3 = new Date()
ref3.set data3, (err) ->
elapsed = new Date().getTime() - t3.getTime()
console.log 'set3 finished ('+elapsed+'ms) - err is '+err
get_data.coffee
Firebase = require 'firebase'
firebaseUrl = 'https://my_firebase.firebaseio.com/same_location'
ref1 = new Firebase firebaseUrl
ref1.on 'value', (snapshot) -> console.log 'remote same_location changed to ' + Buffer.byteLength((snapshot.val() or ''), 'utf8') + ' bytes'
set_data.coffee的输出
data1 2000000 bytes
data2 3000000 bytes
data3 100 bytes
local same_location changed to 2000000 bytes
local same_location changed to 3000000 bytes
local same_location changed to 100 bytes
set1 finished (118314ms) - err is null
set2 finished (149844ms) - err is null
set3 finished (149845ms) - err is null
来自get_data.coffee的输出
remote same_location changed to 0 bytes
remote same_location changed to 2000000 bytes
remote same_location changed to 3000000 bytes
remote same_location changed to 100 bytes