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 ]);
|
||||
}
|
||||
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,
|
||||
([ "_service" : service,
|
||||
"_location" : location,
|
||||
|
@ -551,22 +560,24 @@ static linkSet(service, location, source) {
|
|||
}
|
||||
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))
|
||||
string mc = "_notice_unlink";
|
||||
service = service || 0;
|
||||
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
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) ||
|
||||
(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));
|
||||
// sLocation?
|
||||
register_location(candidate, 0);
|
||||
|
@ -1049,7 +1060,6 @@ case "_set_password":
|
|||
if (checkPassword(vars["_password"], vars["_method"], nonce, vars))
|
||||
#endif
|
||||
{
|
||||
string scheme;
|
||||
mixed *u;
|
||||
|
||||
// TODO? add support for integer _service means multiple
|
||||
|
@ -1084,8 +1094,11 @@ case "_set_password":
|
|||
return display;
|
||||
}
|
||||
#endif
|
||||
scheme = v("scheme");
|
||||
#if 1
|
||||
#if 0
|
||||
// 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
|
||||
// morph. this may not be the very best
|
||||
// solution, but until person/user is rewritten
|
||||
|
@ -1108,13 +1121,13 @@ case "_set_password":
|
|||
// allows two psyc clients to be logged in
|
||||
// concurrently and is very suspicious
|
||||
if (query_once_interactive(ME)
|
||||
|| (scheme && scheme != "psyc")) {
|
||||
|| (v("scheme") && v("scheme") != "psyc")) {
|
||||
// temporary fix for initially created psyc
|
||||
// users. (they dont have a scheme)
|
||||
object o;
|
||||
save();
|
||||
if (interactive(ME)) {
|
||||
linkDel();
|
||||
// linkDel(); doesn't make sense here
|
||||
remove_interactive(ME);
|
||||
}
|
||||
o = named_clone(PSYC_PATH "user", MYNICK);
|
||||
|
@ -1172,7 +1185,7 @@ case "_set_password":
|
|||
// language support for clients..
|
||||
// done in w() instead.
|
||||
vars["_INTERNAL_origin"]->sTextPath(v("layout"),
|
||||
v("language"), scheme);
|
||||
v("language"), v("scheme"));
|
||||
#endif
|
||||
// yeah right..
|
||||
//unless (interactive()) vSet("host", source);
|
||||
|
@ -2637,13 +2650,14 @@ quit(immediate, variant) {
|
|||
int rc;
|
||||
|
||||
P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME))
|
||||
// keeping services running while logging out should be possible.. but
|
||||
// we currently don't do that -- now we do
|
||||
linkDel(0, previous_object());
|
||||
#if 0
|
||||
#if 1
|
||||
// keeping services running while logging out should be possible..
|
||||
// will this unlink all main clients? should it?
|
||||
linkDel(0); // 0, previous_object()); <- this can be ME and will fail
|
||||
#else
|
||||
if (sizeof(v("locations"))) { // this should only trigger at first pass
|
||||
linkCleanUp();
|
||||
#if 1 //def PARANOID
|
||||
# if 1 //def PARANOID
|
||||
if (sizeof(v("locations"))) {
|
||||
P1(("%O * Hey, linkCleanUp left us with %O\n",
|
||||
ME, v("locations")))
|
||||
|
@ -2651,7 +2665,7 @@ quit(immediate, variant) {
|
|||
// breaks when we do
|
||||
vSet("locations", ([]));
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if (immediate == 1 || (immediate && find_call_out(#'quit) != -1)) { //'
|
||||
|
|
|
@ -474,9 +474,11 @@ int disconnected(string remaining) {
|
|||
#endif
|
||||
// wow.. a sincerely expected disconnect!
|
||||
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",
|
||||
object_name(ME) +" · lost PSYC circuit");
|
||||
#else
|
||||
P1(("%O disconnected unexpectedly\n", ME))
|
||||
#endif
|
||||
return 0; // unexpected
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ inherit PSYC_PATH "circuit";
|
|||
// keep a list of objects to ->disconnected() when the driver tells us
|
||||
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)
|
||||
disconnect_notifies = ({ });
|
||||
disconnect_notifies += ({ user });
|
||||
|
@ -54,11 +55,10 @@ protected quit() { QUIT }
|
|||
|
||||
// self-destruct when the TCP link gets lost
|
||||
disconnected(remaining) {
|
||||
P2(( "%O got disconnected.\n", ME))
|
||||
// emulate disconnected() for net/psyc/user
|
||||
if (disconnect_notifies) {
|
||||
foreach (object t : disconnect_notifies)
|
||||
if (t) t->disconnected();
|
||||
if (disconnect_notifies) foreach (object t : disconnect_notifies) {
|
||||
P3(( "%O disconnecting %O\n", ME, t))
|
||||
if (t) t->link_disconnected();
|
||||
}
|
||||
::disconnected(remaining);
|
||||
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
|
||||
//
|
||||
// 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 <net.h>
|
||||
|
@ -12,14 +13,19 @@ logon() {
|
|||
#ifdef NO_EXTERNAL_LOGINS
|
||||
return destruct(ME);
|
||||
#endif
|
||||
#if 0
|
||||
// psyc users dont have their own socket, so the driver
|
||||
// does not call disconnected() for them - this enables the
|
||||
// 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.
|
||||
// rare, but does indeed happen sometimes.
|
||||
else return destruct(ME);
|
||||
|
||||
// i presume the else case is better handled by disconnected() --lynX
|
||||
#endif
|
||||
// no lang support here either
|
||||
vSet("scheme", "psyc");
|
||||
return ::logon();
|
||||
|
@ -27,10 +33,10 @@ logon() {
|
|||
|
||||
// errors only, it says
|
||||
pr(mc, fmt, a,b,c,d,e,f,g,h) {
|
||||
#if 1 //def PRO_PATH
|
||||
if (abbrev("_message",mc)) return;
|
||||
if (v("location"))
|
||||
sendmsg(v("location"), mc+"_print", sprintf(fmt, a,b,c,d,e,f,g,h) );
|
||||
#if 1 //ndef DEVELOPMENT
|
||||
//if (abbrev("_message",mc)) return;
|
||||
foreach (string location : v("locations")[0])
|
||||
sendmsg(location, mc+"_print", sprintf(fmt, a,b,c,d,e,f,g,h) );
|
||||
#else
|
||||
// checkVar() still calls pr() .... grmlblmblm TODO
|
||||
raise_error("pr() called\n");
|
||||
|
|
|
@ -183,9 +183,14 @@ int disconnected(string remaining) {
|
|||
#endif
|
||||
// wow.. a sincerely expected disconnect!
|
||||
if (flags & TCP_PENDING_DISCONNECT) return 1;
|
||||
#ifdef _flag_enable_report_failure_network_circuit_disconnect
|
||||
monitor_report("_failure_network_circuit_disconnect",
|
||||
object_name(ME) +" · lost PSYC circuit");
|
||||
return 0; // unexpected
|
||||
#else
|
||||
P1(("%O disconnected unexpectedly\n", ME))
|
||||
#endif
|
||||
return 0; // unexpected
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
volatile array(object) disconnect_notifies;
|
||||
|
||||
void do_notify_on_disconnect(object user) {
|
||||
void register_link(object user) {
|
||||
unless(disconnect_notifies)
|
||||
disconnect_notifies = ({ });
|
||||
disconnect_notifies += ({ user });
|
||||
|
@ -54,7 +54,7 @@ disconnected(remaining) {
|
|||
// emulate disconnect() for net/psyc/user
|
||||
if (disconnect_notifies) {
|
||||
foreach (object t : disconnect_notifies)
|
||||
if (t) t->disconnected();
|
||||
if (t) t->link_disconnected();
|
||||
}
|
||||
rc = ::disconnected(remaining);
|
||||
destruct(ME);
|
||||
|
|
|
@ -1760,16 +1760,23 @@ 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
|
||||
// if you don't like this default behaviour, override it
|
||||
//
|
||||
// we also call this manually from _request_unlink_disconnect
|
||||
disconnected(remainder) {
|
||||
P2(("disconnected(%O) called in %O\nlocations: %O\n", remainder, ME, v("locations")))
|
||||
// if there are any catch-all connections left don't quit, just delete link
|
||||
if (member(v("locations"), 0) && sizeof(v("locations")[0]) > 1)
|
||||
return linkDel(0, previous_object());
|
||||
|
||||
P2(("disconnected(%O) in %O from %O\n",
|
||||
remainder, ME, previous_object()))
|
||||
// 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
|
||||
// check the lastlog if that's not enough.
|
||||
|
|
Loading…
Reference in a new issue