skynet熱更方式總結

丁玲隆咚嗆發表於2020-11-16

skynet因為require有快取,不能像如下方式熱更:

package.loaded[module] = nil
require(module)

雖然可以如下這樣清下快取:

local cache = require "skynet.codecache"
cache.clear()

但是這樣的成本比較大。只更新一個指令碼,卻把所有指令碼的快取清了。
skynet的DebugConsole服務提供一個更新service的方法:inject。
inject address script 將 script 名字對應的指令碼插入到指定服務中執行(通常可用於熱更新補丁)。
其原理就是修改skynet.dispatch的upvalue,如

--我們的服務裡
skynet.dispatch("lua", function(session, source, cmd,...)
		local f = assert(CMD[cmd])
		skynet.ret(skynet.pack(f(...)))
	end)

我們就可以修改CMD。如下面的patch.lua指令碼:

local CMD = _P.lua.CMD
CMD.test = function() 
	print('new')
end

如果需要更通用的熱更方式可以參考雲風的
如何讓 lua 做盡量正確的熱更新

如果模組新增約束條件,沒有初始化程式,可以參考:jinq0123/hotfix

相關文章