Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8901883
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T01:28:18+00:00 2026-06-15T01:28:18+00:00

I am building a simple gen_server module which monitors activity of multiple remote nodes

  • 0

I am building a simple gen_server module which monitors activity of multiple remote nodes

When a remote node registers, this module monitors the node with erlang:monitor_node(Node, true). This is registered only once per node (confirmed with logs)

and in a handle_info/2 callback of gen_server, it catches {nodedown, Node} message and demonitors the node with erlang:monitor_node(Node, false). I expect to receive this message only once: when the remote node is down.

When I was testing the module, I found that when a remote node goes down, hundreds of {nodedown, Node} messages (the number varies from few hundreds to few thousands) are sent to the gen_server.

Why are multiple messages sent by monitor_node? How can I prevent this behaviour?

EDIT: here is (a part of) the source code

register_node(#node_info{node = NodeName} = NodeInfo) ->
    case mnesia:read(node_info, NodeName) of
        [] ->
            monitor_node(NodeName, true),
            error_logger:info_msg("node ~p registered", [NodeName]);
        [_OldInfo] ->
            error_logger:trace_msg("info of node ~p updated", [NodeName])
    end,
    mnesia:write(NodeInfo).

handle_cast({register_node, #node_info{} = NodeStatus}, Timer) ->
    case mnesia:transaction(fun register_node/1, [NodeStatus]) of
        {aborted, Reason} ->
            error_logger:warning_msg("transaction register_node failed: ~p", [Reason]);
        _ ->
        ok
    end,
    {noreply, Timer};
handle_cast({shutdown_node, #node_info{} = NodeStatus}, Timer) ->
    case mnesia:dirty_delete_object(NodeStatus) of
        {aborted, Reason} ->
            error_logger:warning_msg("transaction shutdown_node failed: ~p", [Reason]);
        _ ->
        ok
    end,
    {noreply, Timer};
handle_cast(Message, Timer) ->
    error_logger:warning_msg("~p: received unknown message ~p", [?MODULE, Message]),
    {noreply, Timer}.

handle_info({nodedown, Node}, Timer) ->
    monitor_node(Node, false),
    error_logger:info_msg("~p: node ~p down", [?MODULE, Node]),
    mnesia:transaction(fun mnesia:delete/3, [node_info, Node, write]),
    {noreply, Timer};
handle_info(Message, Timer) ->
    error_logger:warning_msg("~p: received unknown message ~p", [?MODULE, Message]),
    {noreply, Timer}.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T01:28:19+00:00Added an answer on June 15, 2026 at 1:28 am

    You have done monitor_node(NodeName, true) **INSIDE** the mnesia transaction.

    I think that because monitor_node will involve (I/O operation) message communication internally.
    It is not suitable to put this line inside transation. It maybe send handreds of 'registered' message to the involved node. So that when the node became down, handreds of 'nodedown' messages have been received.

        If a process has made two calls to monitor_node(Node, true) and Node terminates, 
    **two nodedown messages are delivered to the process.** If there is no connection 
    to Node, there will be an attempt to create one. If this fails, a nodedown 
    message is delivered.
    

    Please move the line out of transaction or just use "CASE" expression, and try again.

    register_node(#node_info{node = NodeName} = NodeInfo) ->
        case mnesia:read(node_info, NodeName) of
            [] ->
                monitor_node(NodeName, true),
                error_logger:info_msg("node ~p registered", [NodeName]);
            [_OldInfo] ->
                error_logger:trace_msg("info of node ~p updated", [NodeName])
        end,
        mnesia:write(NodeInfo).
    handle_cast({register_node, #node_info{} = NodeStatus}, Timer) ->
        case mnesia:transaction(fun register_node/1, [NodeStatus]) of
            {aborted, Reason} ->
                error_logger:warning_msg("transaction register_node failed: ~p", [Reason]);
            _ ->
            ok
        end,
        {noreply, Timer};
    

    explanation of side-effect in mnesia transaction

    Mnesia dynamically sets and releases locks as transactions execute,
    therefore, it is very dangerous to execute code with transaction
    side-effects. In particular, a receive statement inside a transaction
    can lead to a situation where the transaction hangs and never returns,
    which in turn can cause locks not to release. This situation could
    bring the whole system to a standstill since other transactions which
    execute in other processes, or on other nodes, are forced to wait for
    the defective transaction.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Im building a simple chat client which is only supposed to be able to
I am building a simple Point of Sale system for my project. This system
I am building simple HTML pages and I want to use this kind of
I'm building a simple HTML/CSS template for myself, which is here , and it
I'm building simple application for myself in JSP which stores URL for me and
I am building simple shopping cart. This is the route, where is are the
I`m building simple app which shows information about most car brands. I have rootViewController
I am building simple notificiation system and I just wanted to know what is
I'm building a simple availability calendar with PHP and MySQL. I have a table
I'm building a simple contact form for a website. It does not connect to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.