【发布时间】:2011-05-19 16:50:42
【问题描述】:
编辑
我有两个模块,在从字典中获取时都会导致错误的 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}.
然后我 set_peer_state 设置一个对等体字典(每个对等体 1 个唯一)该字典保存下载和上传(队列和速度),我将其添加到主 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};
到目前为止,这似乎有效。但是当我尝试更新种子状态时,它会在从字典中获取时崩溃。
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;
这是两个内部函数
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}.
会不会是向 setter 传递不正确的数据导致服务器崩溃? 还是国家在此过程中迷失了方向? 这种做法似乎让所有新字典都存储在旧字典中很乱,有没有更好的方法来处理这种数据结构(每个节点的主要种子和数据)?
我知道我可以从列表中制作字典,但是在我测试这个模块的时候它让我的想法变得混乱。
谢谢
【问题讨论】:
标签: erlang