mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
unlink detection rewrite - please test this
This commit is contained in:
parent
6b8e138eb4
commit
b4867481f4
7 changed files with 70 additions and 36 deletions
|
@ -525,6 +525,15 @@ static linkSet(service, location, source) {
|
||||||
v("locations")[service] = ([ location ]);
|
v("locations")[service] = ([ location ]);
|
||||||
}
|
}
|
||||||
register_location(location, ME);
|
register_location(location, ME);
|
||||||
|
// let me know if you lose the connection to my link!
|
||||||
|
object circuit = find_target_handler(location);
|
||||||
|
if (objectp(circuit)) {
|
||||||
|
P3(("linkSet: registering disc notify for %O from %O.\n",
|
||||||
|
location, circuit))
|
||||||
|
circuit -> register_link(ME);
|
||||||
|
}
|
||||||
|
// probably should go to the user instead
|
||||||
|
else P1(("Warning for %O: Location %O will ghost.\n", MYNICK, location))
|
||||||
if (service) sendmsg(source, "_notice_link_service", 0,
|
if (service) sendmsg(source, "_notice_link_service", 0,
|
||||||
([ "_service" : service,
|
([ "_service" : service,
|
||||||
"_location" : location,
|
"_location" : location,
|
||||||
|
@ -551,22 +560,24 @@ static linkSet(service, location, source) {
|
||||||
}
|
}
|
||||||
P2(("locations after linkSet: %O\n", v("locations")))
|
P2(("locations after linkSet: %O\n", v("locations")))
|
||||||
}
|
}
|
||||||
static linkDel(service, source, variant) {
|
linkDel(service, source, variant) {
|
||||||
P3(("linkDel(%O, %O, %O) called in %O!\n", service, source, variant, ME))
|
P3(("linkDel(%O, %O, %O) called in %O!\n", service, source, variant, ME))
|
||||||
string mc = "_notice_unlink";
|
string mc = "_notice_unlink";
|
||||||
service = service || 0;
|
service = service || 0;
|
||||||
|
|
||||||
unless (member(v("locations"), service)) {
|
unless (member(v("locations"), service)) {
|
||||||
P3(("linkDel(%O, %O) called in %O: no such candidate!\n",
|
P4(("linkDel(%O, %O) called in %O: no such candidate!\n",
|
||||||
service, source, ME));
|
service, source, ME));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
foreach(string candidate : v("locations")[service]) {
|
foreach(string candidate : v("locations")[service]) {
|
||||||
|
P4(("linkDel(%O, %O) in %O: unlinking %O ? handler = %O\n",
|
||||||
|
service, source, ME, candidate, find_target_handler(candidate)));
|
||||||
if ((objectp(source) && find_target_handler(candidate) != source) ||
|
if ((objectp(source) && find_target_handler(candidate) != source) ||
|
||||||
(source && !objectp(source) && candidate != source)) continue;
|
(source && !objectp(source) && candidate != source)) continue;
|
||||||
P2(("linkDel(%O, %O) called in %O: unlinking %O.\n",
|
P2(("linkDel(%O, %O) in %O: unlinking %O.\n",
|
||||||
service, source, ME, candidate));
|
service, source, ME, candidate));
|
||||||
// sLocation?
|
// sLocation?
|
||||||
register_location(candidate, 0);
|
register_location(candidate, 0);
|
||||||
|
@ -1049,7 +1060,6 @@ case "_set_password":
|
||||||
if (checkPassword(vars["_password"], vars["_method"], nonce, vars))
|
if (checkPassword(vars["_password"], vars["_method"], nonce, vars))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
string scheme;
|
|
||||||
mixed *u;
|
mixed *u;
|
||||||
|
|
||||||
// TODO? add support for integer _service means multiple
|
// TODO? add support for integer _service means multiple
|
||||||
|
@ -1084,8 +1094,11 @@ case "_set_password":
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
scheme = v("scheme");
|
#if 0
|
||||||
#if 1
|
// no new link should throw out interactives or other links!
|
||||||
|
// this must be from the days when we had no disconnect notification
|
||||||
|
// so it would remove ghosts of itself..
|
||||||
|
// his should be unnecessary by now! --lynX 2011
|
||||||
// <el> in other cases this is done by
|
// <el> in other cases this is done by
|
||||||
// morph. this may not be the very best
|
// morph. this may not be the very best
|
||||||
// solution, but until person/user is rewritten
|
// solution, but until person/user is rewritten
|
||||||
|
@ -1108,13 +1121,13 @@ case "_set_password":
|
||||||
// allows two psyc clients to be logged in
|
// allows two psyc clients to be logged in
|
||||||
// concurrently and is very suspicious
|
// concurrently and is very suspicious
|
||||||
if (query_once_interactive(ME)
|
if (query_once_interactive(ME)
|
||||||
|| (scheme && scheme != "psyc")) {
|
|| (v("scheme") && v("scheme") != "psyc")) {
|
||||||
// temporary fix for initially created psyc
|
// temporary fix for initially created psyc
|
||||||
// users. (they dont have a scheme)
|
// users. (they dont have a scheme)
|
||||||
object o;
|
object o;
|
||||||
save();
|
save();
|
||||||
if (interactive(ME)) {
|
if (interactive(ME)) {
|
||||||
linkDel();
|
// linkDel(); doesn't make sense here
|
||||||
remove_interactive(ME);
|
remove_interactive(ME);
|
||||||
}
|
}
|
||||||
o = named_clone(PSYC_PATH "user", MYNICK);
|
o = named_clone(PSYC_PATH "user", MYNICK);
|
||||||
|
@ -1172,7 +1185,7 @@ case "_set_password":
|
||||||
// language support for clients..
|
// language support for clients..
|
||||||
// done in w() instead.
|
// done in w() instead.
|
||||||
vars["_INTERNAL_origin"]->sTextPath(v("layout"),
|
vars["_INTERNAL_origin"]->sTextPath(v("layout"),
|
||||||
v("language"), scheme);
|
v("language"), v("scheme"));
|
||||||
#endif
|
#endif
|
||||||
// yeah right..
|
// yeah right..
|
||||||
//unless (interactive()) vSet("host", source);
|
//unless (interactive()) vSet("host", source);
|
||||||
|
@ -2637,10 +2650,11 @@ quit(immediate, variant) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME))
|
P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME))
|
||||||
// keeping services running while logging out should be possible.. but
|
#if 1
|
||||||
// we currently don't do that -- now we do
|
// keeping services running while logging out should be possible..
|
||||||
linkDel(0, previous_object());
|
// will this unlink all main clients? should it?
|
||||||
#if 0
|
linkDel(0); // 0, previous_object()); <- this can be ME and will fail
|
||||||
|
#else
|
||||||
if (sizeof(v("locations"))) { // this should only trigger at first pass
|
if (sizeof(v("locations"))) { // this should only trigger at first pass
|
||||||
linkCleanUp();
|
linkCleanUp();
|
||||||
# if 1 //def PARANOID
|
# if 1 //def PARANOID
|
||||||
|
|
|
@ -474,9 +474,11 @@ int disconnected(string remaining) {
|
||||||
#endif
|
#endif
|
||||||
// wow.. a sincerely expected disconnect!
|
// wow.. a sincerely expected disconnect!
|
||||||
if (flags & TCP_PENDING_DISCONNECT) return 1;
|
if (flags & TCP_PENDING_DISCONNECT) return 1;
|
||||||
#ifndef _flag_disable_report_failure_network_circuit_disconnect
|
#ifdef _flag_enable_report_failure_network_circuit_disconnect
|
||||||
monitor_report("_failure_network_circuit_disconnect",
|
monitor_report("_failure_network_circuit_disconnect",
|
||||||
object_name(ME) +" · lost PSYC circuit");
|
object_name(ME) +" · lost PSYC circuit");
|
||||||
|
#else
|
||||||
|
P1(("%O disconnected unexpectedly\n", ME))
|
||||||
#endif
|
#endif
|
||||||
return 0; // unexpected
|
return 0; // unexpected
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ inherit PSYC_PATH "circuit";
|
||||||
// keep a list of objects to ->disconnected() when the driver tells us
|
// keep a list of objects to ->disconnected() when the driver tells us
|
||||||
volatile array(object) disconnect_notifies;
|
volatile array(object) disconnect_notifies;
|
||||||
|
|
||||||
void do_notify_on_disconnect(object user) {
|
void register_link(object user) {
|
||||||
|
P4(("disconnect_notifies for %O in %O\n", user, ME))
|
||||||
unless(disconnect_notifies)
|
unless(disconnect_notifies)
|
||||||
disconnect_notifies = ({ });
|
disconnect_notifies = ({ });
|
||||||
disconnect_notifies += ({ user });
|
disconnect_notifies += ({ user });
|
||||||
|
@ -54,11 +55,10 @@ protected quit() { QUIT }
|
||||||
|
|
||||||
// self-destruct when the TCP link gets lost
|
// self-destruct when the TCP link gets lost
|
||||||
disconnected(remaining) {
|
disconnected(remaining) {
|
||||||
P2(( "%O got disconnected.\n", ME))
|
|
||||||
// emulate disconnected() for net/psyc/user
|
// emulate disconnected() for net/psyc/user
|
||||||
if (disconnect_notifies) {
|
if (disconnect_notifies) foreach (object t : disconnect_notifies) {
|
||||||
foreach (object t : disconnect_notifies)
|
P3(( "%O disconnecting %O\n", ME, t))
|
||||||
if (t) t->disconnected();
|
if (t) t->link_disconnected();
|
||||||
}
|
}
|
||||||
::disconnected(remaining);
|
::disconnected(remaining);
|
||||||
QUIT // returns unexpected.. TODO
|
QUIT // returns unexpected.. TODO
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// $Id: user.c,v 1.15 2008/12/09 19:27:32 lynx Exp $ // vim:syntax=lpc
|
// $Id: user.c,v 1.15 2008/12/09 19:27:32 lynx Exp $ // vim:syntax=lpc
|
||||||
//
|
//
|
||||||
// handler for PSYC clients
|
// should be a dummy user object since all user objects
|
||||||
|
// must be able to handle PSYC clients
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
@ -12,14 +13,19 @@ logon() {
|
||||||
#ifdef NO_EXTERNAL_LOGINS
|
#ifdef NO_EXTERNAL_LOGINS
|
||||||
return destruct(ME);
|
return destruct(ME);
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
// psyc users dont have their own socket, so the driver
|
// psyc users dont have their own socket, so the driver
|
||||||
// does not call disconnected() for them - this enables the
|
// does not call disconnected() for them - this enables the
|
||||||
// psyc socket to do that
|
// psyc socket to do that
|
||||||
if (this_interactive()) this_interactive()->do_notify_on_disconnect(ME);
|
// basically a good idea, but the wrong place to do this. since we
|
||||||
|
// want to be notified about any of n possible psyc clients we need
|
||||||
|
// to do this in linkSet(). --lynX
|
||||||
|
if (this_interactive()) this_interactive()->register_link(ME);
|
||||||
// connection that is creating us, died while we got here.
|
// connection that is creating us, died while we got here.
|
||||||
// rare, but does indeed happen sometimes.
|
// rare, but does indeed happen sometimes.
|
||||||
else return destruct(ME);
|
else return destruct(ME);
|
||||||
|
// i presume the else case is better handled by disconnected() --lynX
|
||||||
|
#endif
|
||||||
// no lang support here either
|
// no lang support here either
|
||||||
vSet("scheme", "psyc");
|
vSet("scheme", "psyc");
|
||||||
return ::logon();
|
return ::logon();
|
||||||
|
@ -27,10 +33,10 @@ logon() {
|
||||||
|
|
||||||
// errors only, it says
|
// errors only, it says
|
||||||
pr(mc, fmt, a,b,c,d,e,f,g,h) {
|
pr(mc, fmt, a,b,c,d,e,f,g,h) {
|
||||||
#if 1 //def PRO_PATH
|
#if 1 //ndef DEVELOPMENT
|
||||||
if (abbrev("_message",mc)) return;
|
//if (abbrev("_message",mc)) return;
|
||||||
if (v("location"))
|
foreach (string location : v("locations")[0])
|
||||||
sendmsg(v("location"), mc+"_print", sprintf(fmt, a,b,c,d,e,f,g,h) );
|
sendmsg(location, mc+"_print", sprintf(fmt, a,b,c,d,e,f,g,h) );
|
||||||
#else
|
#else
|
||||||
// checkVar() still calls pr() .... grmlblmblm TODO
|
// checkVar() still calls pr() .... grmlblmblm TODO
|
||||||
raise_error("pr() called\n");
|
raise_error("pr() called\n");
|
||||||
|
|
|
@ -183,9 +183,14 @@ int disconnected(string remaining) {
|
||||||
#endif
|
#endif
|
||||||
// wow.. a sincerely expected disconnect!
|
// wow.. a sincerely expected disconnect!
|
||||||
if (flags & TCP_PENDING_DISCONNECT) return 1;
|
if (flags & TCP_PENDING_DISCONNECT) return 1;
|
||||||
|
#ifdef _flag_enable_report_failure_network_circuit_disconnect
|
||||||
monitor_report("_failure_network_circuit_disconnect",
|
monitor_report("_failure_network_circuit_disconnect",
|
||||||
object_name(ME) +" · lost PSYC circuit");
|
object_name(ME) +" · lost PSYC circuit");
|
||||||
|
#else
|
||||||
|
P1(("%O disconnected unexpectedly\n", ME))
|
||||||
|
#endif
|
||||||
return 0; // unexpected
|
return 0; // unexpected
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// respond to the first empty packet
|
// respond to the first empty packet
|
||||||
|
|
|
@ -15,7 +15,7 @@ inherit NET_PATH "spyc/circuit";
|
||||||
// keep a list of objects to ->disconnected() when the driver tells us
|
// keep a list of objects to ->disconnected() when the driver tells us
|
||||||
volatile array(object) disconnect_notifies;
|
volatile array(object) disconnect_notifies;
|
||||||
|
|
||||||
void do_notify_on_disconnect(object user) {
|
void register_link(object user) {
|
||||||
unless(disconnect_notifies)
|
unless(disconnect_notifies)
|
||||||
disconnect_notifies = ({ });
|
disconnect_notifies = ({ });
|
||||||
disconnect_notifies += ({ user });
|
disconnect_notifies += ({ user });
|
||||||
|
@ -54,7 +54,7 @@ disconnected(remaining) {
|
||||||
// emulate disconnect() for net/psyc/user
|
// emulate disconnect() for net/psyc/user
|
||||||
if (disconnect_notifies) {
|
if (disconnect_notifies) {
|
||||||
foreach (object t : disconnect_notifies)
|
foreach (object t : disconnect_notifies)
|
||||||
if (t) t->disconnected();
|
if (t) t->link_disconnected();
|
||||||
}
|
}
|
||||||
rc = ::disconnected(remaining);
|
rc = ::disconnected(remaining);
|
||||||
destruct(ME);
|
destruct(ME);
|
||||||
|
|
|
@ -1760,16 +1760,23 @@ quit(immediate, variant) {
|
||||||
return ::quit(immediate, variant);
|
return ::quit(immediate, variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link_disconnected() {
|
||||||
|
P3(("link_disconnected in %O from %O\nlocations: %O\n", ME, previous_object(), v("locations")))
|
||||||
|
linkDel(0, previous_object());
|
||||||
|
// if there are any catch-all connections left don't quit,
|
||||||
|
// just delete link
|
||||||
|
if (member(v("locations"), 0) && sizeof(v("locations")[0])) return;
|
||||||
|
// unless we have a legacy client, let's get outta here
|
||||||
|
unless (interactive(ME)) disconnected();
|
||||||
|
}
|
||||||
|
|
||||||
// driver calls us here to tell us we lost the connection
|
// driver calls us here to tell us we lost the connection
|
||||||
// if you don't like this default behaviour, override it
|
// if you don't like this default behaviour, override it
|
||||||
//
|
//
|
||||||
// we also call this manually from _request_unlink_disconnect
|
// we also call this manually from _request_unlink_disconnect
|
||||||
disconnected(remainder) {
|
disconnected(remainder) {
|
||||||
P2(("disconnected(%O) called in %O\nlocations: %O\n", remainder, ME, v("locations")))
|
P2(("disconnected(%O) in %O from %O\n",
|
||||||
// if there are any catch-all connections left don't quit, just delete link
|
remainder, ME, previous_object()))
|
||||||
if (member(v("locations"), 0) && sizeof(v("locations")[0]) > 1)
|
|
||||||
return linkDel(0, previous_object());
|
|
||||||
|
|
||||||
// user did not detach his client properly. we'll make a wild guess
|
// user did not detach his client properly. we'll make a wild guess
|
||||||
// at how many messages he may have missed - enough to make the user
|
// at how many messages he may have missed - enough to make the user
|
||||||
// check the lastlog if that's not enough.
|
// check the lastlog if that's not enough.
|
||||||
|
|
Loading…
Reference in a new issue