J'ai créé un module qui gère de manière transparente certains fichiers de manière complètement différente, en remplacement des file:open/2
d'Erlang et du descripteur IoDevice/fichier qu'il renvoie. Dans de nombreux cas, il renvoie simplement le résultat du file:open/2
d'Erlang, et dans d'autres cas il renvoie un IoDevice personnalisé qui lit et écrit via une API HTTP (CloudFiles ou AWS S3).Comment gérer les fichiers ouverts via un Erlang gen_server?
Récemment, c'était un module simple, mais j'ai essayé de le convertir en un gen_server
pour mieux gérer les appels HTTP asynchrones (entre autres raisons). Ces bits personnalisés fonctionnent bien, mais je rencontre des problèmes en appelant simplement file:open/2
à partir d'un gen_server:handle_call/3
et en retournant l'IoDevice résultant. Le problème est après que mon gen_server
ouvre un fichier afin de répondre avec un IoDevice, il y a un appel immédiat, inattendu à gen_server:handle_info/2
et un délai d'attente éventuel sur mon gen_server
.
...
handle_call({open, Path, Flags}, _From, State) ->
Reply = case handle_external_file(Path) of
false -> file:open(Path, Flags);
true -> external_file:open(Path)
end,
%%
%% Reply is {ok,{file_descriptor,prim_file,{#Port<0.1896>,14}}}
%%
{reply, Reply, State};
...
handle_info(Message, State) ->
%%
%% Message is {#Port<0.1896>,{data,[3,0,0,0,0,0,0,0,0]}}
%%
io:format("UNEXPECTED MESSAGE: ~p~n", [Message]),
{noreply, State}
...
Je suppose que cela est lié à ce qui suit de la documentation:
IODevice est vraiment le pid du processus qui gère le fichier. Ce processus est lié au processus qui a initialement ouvert le fichier. Si un processus auquel l'IoDevice est lié s'arrête, le fichier sera fermé et le processus lui-même sera terminé. Un IoDevice retourné à partir de cet appel peut être utilisé comme argument pour les fonctions IO (voir io (3)).
Est-il possible d'ouvrir un fichier à partir d'un gen_server
, remettre son IODevice à un autre processus?
Je pense que vous devriez laisser le 'gen_server' générer le processus qui utilisera le fichier. puis laissez ce processus ouvrir le fichier et l'utiliser. Il n'est pas possible d'utiliser gen_server pour ouvrir le fichier, mais attendez-vous à ce qu'un processus différent utilise le "descripteur de fichier" retourné –