2016-11-16 2 views
3

J'ai intégré YAWS dans mon application à l'environnement de production, et j'utilise la fonction yaws:start_embedded/4 pour démarrer YAWS.Est-il possible d'ajouter YAWS appmods config à l'exécution?

Ci-dessous mon code:

Id = "my_server", 
GconfList = [{logdir, "./log"}, {id, Id}], 
SconfList = [{docroot, Docroot}, 
    {port, Port}, 
    {listen, Listen}, 
    {appmods, [  
    {"/rest", mod_rest, []}, 
    {"/file", mod_file, []}  
    ]} 
], 
yaws:start_embedded(Docroot, SconfList, GconfList, Id). 

Je voudrais ajouter un autre AppMod, par exemple: {"/upload", mod_upload, []}

Est-il possible d'ajouter les modules d'application lors de l'exécution sans redémarrer PIAN?

Répondre

6

Vous pouvez ajouter des appmods à l'exécution en récupérant d'abord la configuration actuelle, en l'utilisant pour créer une nouvelle configuration contenant vos nouvelles applications, puis en définissant la nouvelle configuration.

  1. Appel yaws_api:getconf/0 pour obtenir un 3-tuple {ok, GlobalConf, ServerConfs}GlobalConf est la configuration globale du pian et ServerConfs est une liste de listes de configurations de serveur pian. La conf globale est un type d'enregistrement nommé gconf et le serveur conf est un type d'enregistrement nommé sconf; Ces deux types d'enregistrements sont définis dans le fichier d'en-tête yaws.hrl.
  2. Parcourez les configurations du serveur pour trouver celle contenant les applications que vous souhaitez modifier. C'est un peu délicat car vous avez affaire à une liste de listes, et vous devez garder la forme de la structure de données globale inchangée.
  3. Une fois que vous avez trouvé le sconf, créez une nouvelle instance sconf en ajoutant votre nouvelle appmod à sa liste actuelle d'applications. Chaque élément de la liste appmod est un tuple composé d'un chemin URL pour l'appmod et du nom du module appmod. Un tuple d'appmod peut également éventuellement contenir un troisième champ constitué d'une liste de chemins sous le premier chemin à exclure; Voir la description de exclude_paths dans the Yaws appmod documentation pour plus de détails. Remplacez la valeur sconf existante par ServerConfs avec votre nouvelle valeur.
  4. Appelez yaws_api:setconf/2 pour définir la nouvelle configuration, en passant le GlobalConf existant comme premier argument et le nouveau ServerConfs contenant votre nouveau sconf comme deuxième argument.

Le module am_extend ci-dessous montre comment procéder. Il exporte une fonction add/1 qui prend une fonction qui permet d'identifier et d'augmenter les applications dans le serveur particulier qui vous intéresse.

-module(am_extend). 
-export([add/1]). 

add(AppmodAdder) -> 
    {ok, GlobalConf, ServerConfs} = yaws_api:getconf(), 
    NewServerConfs = add_appmod(ServerConfs, AppmodAdder), 
    yaws_api:setconf(GlobalConf, NewServerConfs). 

add_appmod(ServerConfs, AppmodAdder) -> 
    lists:foldl(fun(Val, Acc) -> 
         AcC++ [AppmodAdder(A) || A <- Val] 
       end, [], ServerConfs). 

Un exemple d'utilisation de ce code est de passer de la fonction ci-dessous comme argument pour AppmodAdderam_extend:add/1. Pour cet exemple, nous recherchons un serveur qui a un chemin d'appmod "/sse" afin que nous puissions ajouter un autre appmod à ce serveur pour le chemin "/sse2". Tout serveur conf dont nous ne nous soucions pas est juste retourné inchangé.

-include_lib("yaws/include/yaws.hrl"). 

add_sse2(#sconf{appmods=AM}=SC) -> 
    case lists:keyfind("/sse", 1, AM) of 
     false -> 
      SC; 
     _ -> 
      SC#sconf{appmods=[{"/sse2", my_sse_module}|AM]} 
    end. 

Notez que notre fonction add_sse2/1 doit être compilé avec yaws.hrl inclus donc il a la définition du dossier disponible sconf.

+1

J'ai essayé le code que vous fournissez, et cela fonctionne, et n'affectera pas l'autre connexion connectée, merci beaucoup! – chengweichao