/** * <p> * Determine if another node is alive. This method has the side effect of * setting up a connection to the remote node (if possible). Only a single * outgoing message is sent; the timeout is how long to wait for a response. * </p> * * <p> * Only a single attempt is made to connect to the remote node, so for * example it is not possible to specify an extremely long timeout and * expect to be notified when the node eventually comes up. If you wish to * wait for a remote node to be started, the following construction may be * useful: * </p> * * <pre> * // ping every 2 seconds until positive response * while (!me.ping(him, 2000)) * ; * </pre> * * @param node * the name of the node to ping. * * @param timeout * the time, in milliseconds, to wait for response before * returning false. * * @return true if the node was alive and the correct ping response was * returned. false if the correct response was not returned on time. */ /* * internal info about the message formats... * * the request: -> REG_SEND {6,#Pid<[email protected]>,'',net_kernel} * {'$gen_call',{#Pid<[email protected]>,#Ref<[email protected]>},{is_auth,bingo@aule}} * * the reply: <- SEND {2,'',#Pid<[email protected]>} {#Ref<[email protected]>,yes} */ public bool ping(String node, long timeout) { if (node.Equals(this.Node)) { return(true); } else if (node.IndexOf('@', 0) < 0 && node.Equals(this.Node.Substring(0, this.Node.IndexOf('@', 0)))) { return(true); } // other node OtpMbox mbox = null; try { mbox = createMbox(true); mbox.send("net_kernel", node, getPingTuple(mbox)); OtpErlangObject reply = mbox.receive(timeout); OtpErlangTuple t = (OtpErlangTuple)reply; OtpErlangAtom a = (OtpErlangAtom)t.elementAt(1); return("yes".Equals(a.atomValue())); } catch (Exception) { } finally { closeMbox(mbox); } return(false); }
/* * this method simulates net_kernel only for the purpose of replying to * pings. */ private bool netKernel(OtpMsg m) { OtpMbox mbox = null; try { OtpErlangTuple t = (OtpErlangTuple)m.getMsg(); OtpErlangTuple req = (OtpErlangTuple)t.elementAt(1); // actual // request OtpErlangPid pid = (OtpErlangPid)req.elementAt(0); // originating // pid OtpErlangObject[] pong = new OtpErlangObject[2]; pong[0] = req.elementAt(1); // his #Ref pong[1] = new OtpErlangAtom("yes"); mbox = createMbox(true); mbox.send(pid, new OtpErlangTuple(pong)); return(true); } catch (Exception) { } finally { closeMbox(mbox); } return(false); }
/** * Close the specified mailbox with the given reason. * * @param mbox * the mailbox to close. * @param reason * an Erlang term describing the reason for the termination. * * <p> * After this operation, the mailbox will no longer be able to * receive messages. Any delivered but as yet unretrieved * messages can still be retrieved however. * </p> * * <p> * If there are links from the mailbox to other * {@link OtpErlangPid pids}, they will be broken when this * method is called and exit signals with the given reason will * be sent. * </p> * */ public void closeMbox(OtpMbox mbox, OtpErlangObject reason) { if (mbox != null) { mboxes.remove(mbox); mbox.Name = null; mbox.breakLinks(reason); } }
/** * Determine the {@link OtpErlangPid pid} corresponding to a registered name * on this node. * * @return the {@link OtpErlangPid pid} corresponding to the registered * name, or null if the name is not known on this node. */ public OtpErlangPid whereis(String name) { OtpMbox m = mboxes.get(name); if (m != null) { return(m.Self); } return(null); }
public OtpMbox create(bool sync) { OtpErlangPid pid = node.createPid(); OtpMbox m = sync ? new OtpMbox(node, pid) : new OtpActorMbox(sched, node, pid); lock (this) { byPid.Add(pid, new WeakReference(m)); } return(m); }
/** * Determine if two mailboxes are equal. * * @return true if both Objects are mailboxes with the same identifying * {@link OtpErlangPid pids}. */ public override bool Equals(Object o) { if (!(o is OtpMbox)) { return(false); } OtpMbox m = (OtpMbox)o; return(m.self.Equals(self)); }
public void remove(OtpMbox mbox) { lock (this) { byPid.Remove(mbox.Self); if (mbox.Name != null) { byName.Remove(mbox.Name); } } }
public bool Equals(OtpMbox o) { if (o is null) { return(false); } if (ReferenceEquals(this, o)) { return(true); } return(Self.Equals(o.Self)); }
public OtpMbox create(String name, bool sync) { OtpMbox m = null; lock (this) { if (get(name) != null) { return(null); } OtpErlangPid pid = node.createPid(); m = sync ? new OtpMbox(node, pid, name) : new OtpActorMbox(sched, node, pid, name); byPid.Add(pid, new WeakReference(m)); byName.Add(name, new WeakReference(m)); } return(m); }
/* * look up a mailbox based on its name. If the mailbox has gone out of * scope we also remove the reference from the hashtable so we don't * find it again. */ public OtpMbox get(String name) { lock (this) { if (byName.ContainsKey(name)) { WeakReference wr = byName[name]; OtpMbox m = (OtpMbox)wr.Target; if (m != null) { return(m); } byName.Remove(name); } return(null); } }
/* create the outgoing ping message */ private OtpErlangTuple getPingTuple(OtpMbox mbox) { OtpErlangObject[] ping = new OtpErlangObject[3]; OtpErlangObject[] pid = new OtpErlangObject[2]; OtpErlangObject[] node = new OtpErlangObject[2]; pid[0] = mbox.Self; pid[1] = createRef(); node[0] = new OtpErlangAtom("is_auth"); node[1] = new OtpErlangAtom(Node); ping[0] = new OtpErlangAtom("$gen_call"); ping[1] = new OtpErlangTuple(pid); ping[2] = new OtpErlangTuple(node); return(new OtpErlangTuple(ping)); }
/* * look up a mailbox based on its pid. If the mailbox has gone out of * scope we also remove the reference from the hashtable so we don't * find it again. */ public OtpMbox get(OtpErlangPid pid) { lock (this) { if (byPid.ContainsKey(pid)) { WeakReference wr = byPid[pid]; OtpMbox m = (OtpMbox)wr.Target; if (m != null) { return(m); } byPid.Remove(pid); } return(null); } }
/* * OtpCookedConnection delivers messages here return true if message was * delivered successfully, or false otherwise. */ public bool deliver(OtpMsg m) { OtpMbox mbox = null; try { int t = m.type(); if (t == OtpMsg.regSendTag) { String name = m.getRecipientName(); /* special case for netKernel requests */ if (name.Equals("net_kernel")) { return(netKernel(m)); } else { mbox = mboxes.get(name); } } else { mbox = mboxes.get(m.getRecipientPid()); } if (mbox == null) { return(false); } mbox.deliver(m); } catch (Exception) { return(false); } return(true); }
public bool register(String name, OtpMbox mbox) { lock (this) { if (name == null) { if (mbox.Name != null) { byName.Remove(mbox.Name); mbox.Name = null; } } else { if (get(name) != null) { return(false); } byName.Add(name, new WeakReference(mbox)); mbox.Name = name; } } return(true); }
/** * Close the specified mailbox with reason 'normal'. * * @param mbox * the mailbox to close. * * <p> * After this operation, the mailbox will no longer be able to * receive messages. Any delivered but as yet unretrieved * messages can still be retrieved however. * </p> * * <p> * If there are links from the mailbox to other * {@link OtpErlangPid pids}, they will be broken when this * method is called and exit signals with reason 'normal' will be * sent. * </p> * */ public void closeMbox(OtpMbox mbox) { closeMbox(mbox, new OtpErlangAtom("normal")); }
public bool register(String name, OtpMbox mbox) { lock (this) { if (name == null) { if (mbox.Name != null) { byName.Remove(mbox.Name); mbox.Name = null; } } else { if (get(name) != null) { return false; } byName.Add(name, new WeakReference(mbox)); mbox.Name = name; } } return true; }
internal MessageEventArgs(OtpMbox mbox, OtpMsg msg) { Mbox = mbox; Msg = msg; }
public static OtpErlangTuple Load(OtpMbox mbox, OtpErlangPid pid, string script) { OtpErlangObject body; OtpErlangBoolean debug = new OtpErlangBoolean(false); OtpErlangObject message; if (script.Length <= 65535) { body = new OtpErlangString(script); } else { body = new OtpErlangBinary(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(script)); } message = new OtpErlangTuple(new OtpErlangObject[] { mbox.Self, new OtpErlangAtom("load"), body, debug }); mbox.send(pid, message); OtpErlangTuple reply = (OtpErlangTuple)mbox.receive(); Console.WriteLine("Load: {0}", reply); return reply; }
/** * <p> * Register or remove a name for the given mailbox. Registering a name for a * mailbox enables others to send messages without knowing the * {@link OtpErlangPid pid} of the mailbox. A mailbox can have at most one * name; if the mailbox already had a name, calling this method will * supercede that name. * </p> * * @param name * the name to register for the mailbox. Specify null to * unregister the existing name from this mailbox. * * @param mbox * the mailbox to associate with the name. * * @return true if the name was available, or false otherwise. */ public bool registerName(String name, OtpMbox mbox) { return mboxes.register(name, mbox); }
/* create the outgoing ping message */ private OtpErlangTuple getPingTuple(OtpMbox mbox) { OtpErlangObject[] ping = new OtpErlangObject[3]; OtpErlangObject[] pid = new OtpErlangObject[2]; OtpErlangObject[] node = new OtpErlangObject[2]; pid[0] = mbox.Self; pid[1] = createRef(); node[0] = new OtpErlangAtom("is_auth"); node[1] = new OtpErlangAtom(Node); ping[0] = new OtpErlangAtom("$gen_call"); ping[1] = new OtpErlangTuple(pid); ping[2] = new OtpErlangTuple(node); return new OtpErlangTuple(ping); }
/** * <p> * Register or remove a name for the given mailbox. Registering a name for a * mailbox enables others to send messages without knowing the * {@link OtpErlangPid pid} of the mailbox. A mailbox can have at most one * name; if the mailbox already had a name, calling this method will * supercede that name. * </p> * * @param name * the name to register for the mailbox. Specify null to * unregister the existing name from this mailbox. * * @param mbox * the mailbox to associate with the name. * * @return true if the name was available, or false otherwise. */ public bool registerName(String name, OtpMbox mbox) { return(mboxes.register(name, mbox)); }