编辑
我有两个模块,从字典中获取时都会导致错误的 args 错误(gen_server 状态)
这是来自一个模块的代码
init([ChunkSize, RunningCounter]) ->
D0 = dict:new(),
D1 = dict:store(chunkSize, ChunkSize, D0),
D2 = dict:store(torrentUploadSpeed, 0, D1),
D3 = dict:store(torrentDownloadSpeed, 0, D2),
TorrentDownloadQueue = queue:new(),
TorrentUploadQueue = queue:new(),
D4 = dict:store(torrentDownloadQueue, TorrentDownloadQueue, D3),
D5 = dict:store(torrentUploadQueue, TorrentUploadQueue, D4),
D6 = dict:store(runningCounter, RunningCounter, D5),
{ok, D6}.
Run Code Online (Sandbox Code Playgroud)
然后我 set_peer_state 设置一个对等字典(每个对等点唯一一个)字典保存下载和上传(队列和速度),我将它添加到主 gen_server 状态(字典)所以我在主中有主要的 torrent 数据字典,每个对等点都有一个字典,由对等点 id 存储。
set_peer_state(Id) ->
gen_server:cast(?SERVER, {setPeerState, Id}).
handle_cast({setPeerState, Id}, State) ->
io:format("In the Set Peer State ~p~n", [dict:fetch(runningCounter, State)]),
Id0 = dict:new(),
PeerDownloadQueue = queue:new(),
PeerUploadQueue = queue:new(),
Id1 = dict:store(peerDownloadQueue, PeerDownloadQueue, Id0),
Id2 = dict:store(peerUploadQueue, PeerUploadQueue, Id1),
Id3 = dict:store(peerDownloadSpeed, 0, Id2),
Id4 = dict:store(peerUploadSpeed, 0, Id3),
D = dict:store(Id, Id4, State),
{noreply, D};
Run Code Online (Sandbox Code Playgroud)
到目前为止,这似乎有效。但是当我尝试更新 torrent 状态时,它在从字典中获取时崩溃了。
handle_cast({updateTorrentDownloadState, Time}, State) ->
% fetch the counter for the speed calculation and queue length
RunningCounter = dict:fetch(runningCounter, State),
% Fetch the Torrents download queue
TorrentDownloadQueue = dict:fetch(torrentDownloadQueue, State),
io:format("The fetched queue is ~p~n", [dict:fetch(torrentDownloadQueue, State)]),
% Add the item to the queue (main torrent upload queue)
TorrentDownloadQueue2 = queue:in(Time, TorrentDownloadQueue),
% Get the lenght of the downloadQueue
TorrentDownloadQueueLength = queue:len(TorrentDownloadQueue2),
% If the queue is larger than the running counter remove item
if
TorrentDownloadQueueLength >= RunningCounter ->
% Remove item from the queue
TorrentDownloadQueue3 = queue:drop(TorrentDownloadQueue2),
update_torrent_download(TorrentDownloadQueue3, State);
TorrentDownloadQueueLength < RunningCounter ->
update_torrent_download(TorrentDownloadQueue2, State)
end;
Run Code Online (Sandbox Code Playgroud)
这是 2 个内部函数
update_torrent_download(TorrentDownloadQueue, State) ->
% Store the queue to the new torrent dict
State2 = dict:store(torrentDownLoadQueue, TorrentDownloadQueue, State),
Speed = calculate_speed(TorrentDownloadQueue, State2),
State3 = dict:store(torrentDownloadSpeed, Speed, State2),
{noreply, State3}.
calculate_speed(Queue, State) ->
List = queue:to_list(Queue),
Sum = lists:sum(List),
Count = queue:len(Queue),
ChunkSize = dict:fetch(chunkSize, State),
Speed = (Count * ChunkSize) div Sum,
{ok, Speed}.
Run Code Online (Sandbox Code Playgroud)
可能是将不正确的数据传递给 setter 会导致服务器崩溃吗?还是国家在此过程中迷失了方向?将所有新字典存储在旧字典中的这种做法似乎很混乱,有没有更好的方法来处理此数据结构(每个对等方的主要种子和数据)?
我知道我可以从列表中制作字典,但是在我测试这个模块的时候我的想法很混乱。
谢谢
你的问题是 State 不是一个 dict。
1> dict:fetch(runningCounter, not_a_dict).
** exception error: {badrecord,dict}
in function dict:get_slot/2
in call from dict:fetch/2
Run Code Online (Sandbox Code Playgroud)