一.現象描述:
更新完服務器,發現無法進入遊戲了,看日誌,沒有任何明顯信息。最後嘗試停服重啓,結果application:stop都不相應。
二.原因分析:沒辦法,只好去分析代碼,這次停服更新,只改了一行代碼,就是解決原來玩家卡死的問題。
解決辦法是當玩家登錄的時候,如果發現原來的進程在,就主動的停掉原來的進程,然後開啓新的進程。自己找了個帳號,上線下線幾次,感覺沒問題,就更新了。
確實是測試不夠啊,這是必現的問題。。。
開始瀏覽了很久的代碼,都沒發現問題,只好去線上看,發現這個supervisor居然阻塞了這麼多消息,那問題肯定是這裏了。
代碼正在執行proc_lib:sync_wait這個函數,百度了一下,發現這個是gen_server實現代碼的一部分。
重新看代碼,玩家上線,supervisor啓動對應的gen_server,gen_server初始化,檢查是否有舊進程數據,發現有,去停掉舊進程。
停掉舊進程:supervisor:delete_child,gen_server:cast
跳轉到supervisor的代碼,發現。。。delete_child是gen_server:call。。。
於是,這裏就進入了死鎖。。。
果然對實現不理解的話,就能搞出bug,無論使用多麼牛逼的語言。。
三.解決方法
stop使用其他方法解決