EDITアーラン辞書フェッチクラッシュ
Iは、2つのモジュールを有し、辞書から(gen_server状態)ここ
をフェッチするときの両方が悪い引数エラーが発生する1つのモジュールからのコードである
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状態(ディクショナリary)だから私はピア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;
と、ここ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}.
は、それがセッターに不正確なデータを渡すと、サーバーがクラッシュすることをだろうか? 途中で状態が失われますか? これを行うこの方法は、古い辞書に保存するすべての新しい辞書では面倒ですが、このデータ構造(各ピアの主なトレントとデータ)を処理するより良い方法はありますか?
私はリストから辞書を作ることができると知っていますが、私はこのモジュールをテストしていた時点で私の心を乱していました。
ありがとうございます。
ありがとうございました。だから、私は自分のモジュールを通してStateを使います。私はこれが州としてのジェネとして役立ったと思ったのですか?状態を辞書サーバとしてジェネラルサーバに定義する必要がありますか? – jarryd
gen_server:castメソッドはメッセージのみを渡しますが、handle_castはメッセージと状態を取ります。どのような状態が分かっていますか?私はこの状態をどこに設定するのですか?私はそれを設定するinitメソッドで行いますが、handle_castメソッドで利用できるように見えませんか?ありがとう – jarryd
問題はあなたがあなたのプログラムのどこかで間違ったことをやっているということですが、あなたが共有するコードにエラーがありません。状態は単なる変数ですが、それを使用しようとしている辞書ではありません。つまり、別の場所で間違って設定してしまうということです。 –