[Erlang 0095] Erlang module_info

Source: Internet
Author: User
In. net, we can use Attribute and reflection to parse Assembly metadata at runtime. Below is a simple example written by C:

 Worker1 worker1 = new Worker1 ();  var attribute = worker1.GetType().GetCustomAttribute(typeof( ProcessOrderAttribute)) as ProcessOrderAttribute ;  Console.WriteLine("Description {0}  Order {1}" , attribute.Descrption, attribute.Order);  Console.ReadLine();[ProcessOrder( " first step", 1)] public class Worker1 { }class ProcessOrderAttribute : Attribute   {       public string Descrption { get; set; }       public int Order { get; set; }       public ProcessOrderAttribute(string description, int order)       {           Descrption = description;           Order = order;       }   }

 

Similar to Erlang, we can also do similar things. We can use module_info to obtain module metadata, such:
(rabbit@nimbus)4> test:module_info().[{exports,[{module_info,0},{module_info,1}]},{imports,[]},{attributes,[{vsn,[64335248162526234078446821625873662118]},              {tag,[generated_by_tool]}]},{compile,[{options,[{d,use_specs},                     {outdir,"/data/rabbitmq-server-3.0.0/ebin"},                     {i,"/data/rabbitmq-server-3.0.0/include"},                     debug_info]},           {version,"4.8"},           {time,{2012,12,12,14,39,42}},           {source,"/data/rabbitmq-server-3.0.0/src/test.erl"}]}](rabbit@nimbus)5>

 

Use metadata in rabbitmq Rabbit_boot_stepTo control the startup process, for example, Rabbit. in ERL, every rabbit_boot_step defines the MFA, preconditions, and description information to be started. When rabbit is started, it starts up in order according to the element information of the module.
-rabbit_boot_step({rabbit_log,                   [{description, "logging server"},                    {mfa,         {rabbit_sup, start_restartable_child,                                   [rabbit_log]}},                    {requires,    external_infrastructure},                    {enables,     kernel_ready}]}).-rabbit_boot_step({rabbit_event,                   [{description, "statistics event manager"},                    {mfa,         {rabbit_sup, start_restartable_child,                                   [rabbit_event]}},                    {requires,    external_infrastructure},                    {enables,     kernel_ready}]}).-rabbit_boot_step({kernel_ready,                   [{description, "kernel ready"},                    {requires,    external_infrastructure}]}).

 

In the rabbit. erl module, we can see how rabbitmq parses module metadata and completes it.

start(normal, []) ->    case erts_version_check() of        ok ->            {ok, Vsn} = application:get_key(rabbit, vsn),            error_logger:info_msg("Starting RabbitMQ ~s on Erlang ~s~n",                                  [Vsn, erlang:system_info(otp_release)]),            {ok, SupPid} = rabbit_sup:start_link(),            true = register(rabbit, self()),            print_banner(),            [ok = run_boot_step(Step) || Step <- boot_steps()],            io:format("~nbroker running~n"),            {ok, SupPid};        Error ->            Error    end. run_boot_step({StepName, Attributes}) ->    Description = case lists:keysearch(description, 1, Attributes) of                      {value, {_, D}} -> D;                      false           -> StepName                  end,    case [MFA || {mfa, MFA} <- Attributes] of        [] ->            io:format("-- ~s~n", [Description]);        MFAs ->            io:format("starting ~-60s ...", [Description]),            [try                 apply(M,F,A)             catch                 _:Reason -> boot_error(Reason, erlang:get_stacktrace())             end || {M,F,A} <- MFAs],            io:format("done~n"),            ok    end.boot_steps() ->    sort_boot_steps(rabbit_misc:all_module_attributes(rabbit_boot_step)).

 

As for the implementation of rabbit_misc: all_module_attributes, it is easy to traverse and load the metadata of all modules:
\rabbitmq-server-3.0.0\src\rabbit_misc.erl all_module_attributes(Name) ->    Modules =        lists:usort(          lists:append(            [Modules || {App, _, _}   <- application:loaded_applications(),                        {ok, Modules} <- [application:get_key(App, modules)]])),    lists:foldl(      fun (Module, Acc) ->              case lists:append([Atts || {N, Atts} <- module_attributes(Module),                                         N =:= Name]) of                  []   -> Acc;                  Atts -> [{Module, Atts} | Acc]              end      end, [], Modules). module_attributes(Module) ->    case catch Module:module_info(attributes) of        {'EXIT', {undef, [{Module, module_info, _} | _]}} ->            io:format("WARNING: module ~p not found, so not scanned for boot steps.~n",                      [Module]),            [];        {'EXIT', Reason} ->            exit(Reason);        V ->            V    end.

 

Example of the call result:

(rabbit@nimbus)5> rabbit_misc:all_module_attributes(rabbit_boot_step).[{rabbit_policy,[{rabbit_policy,[{description,"policy parameters"},                                 {mfa,{rabbit_policy,register,[]}},                                 {requires,rabbit_registry},                                 {enables,recovery}]}]},{rabbit_mirror_queue_misc,[{rabbit_mirror_queue_misc,[{description,"HA policy validation"},                                                       {mfa,{rabbit_registry,register,                                                                             [policy_validator,<<"ha-mode">>,rabbit_mirror_queue_misc]}},                                                       {mfa,{rabbit_registry,register,                                                                             [policy_validator,<<"ha-params">>,                                                                              rabbit_mirror_queue_misc]}},                                                       {requires,rabbit_registry},                                                       {enables,recovery}]}]},{rabbit_exchange_type_topic,[{rabbit_exchange_type_topic,[{description,"exchange type topic"},                                                           {mfa,{rabbit_registry,register,                                                                                 [exchange,<<"topic">>,rabbit_exchange_type_topic]}},                                                           {requires,rabbit_registry},........ 

 

 

Extension: if we need to write rabbitmq extensions, We need to register the modules that rabbit knows about. This registration adds rabbit_boot_step to the modules, add our modules in the appropriate phase of rabbit startup. After registration, you can see the newly registered modules in the rabbit_registry table of ETS. For example, rabbit_exchange_type_recent_history is the newly added exchange.
  (rabbit@nimbus)4> ets:i(rabbit_registry). <1   > {{exchange,'x-recent-history'},rabbit_exchange_type_recent_history}<2   > {{policy_validator,'ha-mode'},rabbit_mirror_queue_misc}<3   > {{policy_validator,'ha-params'},rabbit_mirror_queue_misc}<4   > {{auth_mechanism,'AMQPLAIN'},rabbit_auth_mechanism_amqplain}<5   > {{exchange,topic},rabbit_exchange_type_topic}<6   > {{runtime_parameter,policy},rabbit_policy}<7   > {{auth_mechanism,'PLAIN'},rabbit_auth_mechanism_plain}<8   > {{exchange,headers},rabbit_exchange_type_headers}<9   > {{auth_mechanism,'RABBIT-CR-DEMO'},rabbit_auth_mechanism_cr_demo}<10  > {{exchange,direct},rabbit_exchange_type_direct}<11  > {{exchange,fanout},rabbit_exchange_type_fanout}EOT  (q)uit (p)Digits (k)ill /
I learned a trick with rabbitmq, and I am in a good mood. today, the heavy snow in Beijing reminds me of the beautiful sentence "watching Qingzhu change to qiongzhi when the six flowers go out to the house", a small figure (when I was a child, there was an identical cotton coat ):

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.