Erlang字典提取崩溃

jar*_*ryd 1 erlang

编辑


我有两个模块,从字典中获取时都会导致错误的 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 会导致服务器崩溃吗?还是国家在此过程中迷失了方向?将所有新字典存储在旧字典中的这种做法似乎很混乱,有没有更好的方法来处理此数据结构(每个对等方的主要种子和数据)?

我知道我可以从列表中制作字典,但是在我测试这个模块的时候我的想法很混乱。

谢谢

YOU*_*LID 5

你的问题是 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)