EDITErlang Dictionnaire chercher accident
J'ai deux modules et causent deux mauvaises erreurs args lors de la récupération du dictionnaire (état gen_server)
Voici le code d'un module
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}.
Puis set_peer_state qui met en place un dictionnaire de pairs (1 unique pour chaque pair) Le dictionnaire contient le téléchargement et le téléchargement (file d'attente et vitesse) et je l'ajoute à l'état gen_server principal (diction ary) J'ai donc les données principales de torrent dans le dictionnaire principal avec un dictionnaire pour chaque pair stocké par l'id de pair.
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};
Cela semble fonctionner jusqu'à présent. Mais quand j'essaye de mettre à jour l'état du torrent, il se bloque lors de l'extraction du dictionnaire.
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;
et voici les 2 fonctions internes
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}.
pourrait-il que le passage des données incorrectes aux setters plantage du serveur? Ou l'état se perd-il en cours de route? Cette façon de faire semble désordonnée avec tous les nouveaux dicts à stocker dans l'ancien dict, y a-t-il une meilleure façon de gérer cette structure de données (torrent principal et données pour chaque pair)? Je savais que je pouvais faire les dictionnaires à partir de listes, mais ça me dérangeait au moment où je testais ce module.
Merci
Merci. Donc j'utilise State tout au long de mon module. Je pensais que cela a été géré par gen servir de l'état? L'état doit-il être défini dans le serveur gen en tant que dictionnaire? – jarryd
La méthode gen_server: cast ne transmet qu'un message, mais le handle_cast prend le message et l'état. Comment sait-il ce qu'est l'état? Où dois-je définir cet état? Je le fais dans la méthode init qui le configure, mais il ne semble pas qu'il soit disponible dans la méthode handle_cast? Merci – jarryd
Le problème est que vous faites la mauvaise chose quelque part dans votre programme, mais l'erreur n'est pas dans le code que vous avez partagé. L'état est juste une variable, mais ce n'est pas un dictionnaire où vous essayez de l'utiliser, ce qui signifie que vous l'avez incorrectement défini dans un autre endroit. –