Blame view

publish/skynet/service/datacenterd.lua 1.88 KB
4d6f285d   zhouhaihai   增加发布功能
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
105
106
107
108
109
110
  local skynet = require "skynet"
  
  local command = {}
  local database = {}
  local wait_queue = {}
  local mode = {}
  
  local function query(db, key, ...)
  	if key == nil then
  		return db
  	else
  		return query(db[key], ...)
  	end
  end
  
  function command.QUERY(key, ...)
  	local d = database[key]
  	if d then
  		return query(d, ...)
  	end
  end
  
  local function update(db, key, value, ...)
  	if select("#",...) == 0 then
  		local ret = db[key]
  		db[key] = value
  		return ret, value
  	else
  		if db[key] == nil then
  			db[key] = {}
  		end
  		return update(db[key], value, ...)
  	end
  end
  
  local function wakeup(db, key1, ...)
  	if key1 == nil then
  		return
  	end
  	local q = db[key1]
  	if q == nil then
  		return
  	end
  	if q[mode] == "queue" then
  		db[key1] = nil
  		if select("#", ...) ~= 1 then
  			-- throw error because can't wake up a branch
  			for _,response in ipairs(q) do
  				response(false)
  			end
  		else
  			return q
  		end
  	else
  		-- it's branch
  		return wakeup(q , ...)
  	end
  end
  
  function command.UPDATE(...)
  	local ret, value = update(database, ...)
  	if ret or value == nil then
  		return ret
  	end
  	local q = wakeup(wait_queue, ...)
  	if q then
  		for _, response in ipairs(q) do
  			response(true,value)
  		end
  	end
  end
  
  local function waitfor(db, key1, key2, ...)
  	if key2 == nil then
  		-- push queue
  		local q = db[key1]
  		if q == nil then
  			q = { [mode] = "queue" }
  			db[key1] = q
  		else
  			assert(q[mode] == "queue")
  		end
  		table.insert(q, skynet.response())
  	else
  		local q = db[key1]
  		if q == nil then
  			q = { [mode] = "branch" }
  			db[key1] = q
  		else
  			assert(q[mode] == "branch")
  		end
  		return waitfor(q, key2, ...)
  	end
  end
  
  skynet.start(function()
  	skynet.dispatch("lua", function (_, _, cmd, ...)
  		if cmd == "WAIT" then
  			local ret = command.QUERY(...)
  			if ret then
  				skynet.ret(skynet.pack(ret))
  			else
  				waitfor(wait_queue, ...)
  			end
  		else
  			local f = assert(command[cmd])
  			skynet.ret(skynet.pack(f(...)))
  		end
  	end)
  end)