Skip to content

Commit

Permalink
* move idle handling code to client-connection
Browse files Browse the repository at this point in the history
* generalize init_state source mixin method

git-svn-id: https://xpra.org/svn/Xpra/trunk@18592 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Feb 25, 2018
1 parent d0091b5 commit d576049
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 63 deletions.
41 changes: 5 additions & 36 deletions src/xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import os.path
from time import sleep

from xpra.log import Logger
Expand Down Expand Up @@ -35,9 +34,9 @@

from xpra.os_util import thread, monotonic_time, bytestostr, WIN32, PYTHON3
from xpra.util import typedict, flatten_dict, updict, merge_dicts, envbool, envint, \
SERVER_EXIT, SERVER_ERROR, SERVER_SHUTDOWN, DETACH_REQUEST, NEW_CLIENT, DONE, IDLE_TIMEOUT, SESSION_BUSY, XPRA_IDLE_NOTIFICATION_ID, XPRA_NEW_USER_NOTIFICATION_ID
SERVER_EXIT, SERVER_ERROR, SERVER_SHUTDOWN, DETACH_REQUEST, NEW_CLIENT, DONE, SESSION_BUSY, XPRA_NEW_USER_NOTIFICATION_ID
from xpra.net.bytestreams import set_socket_timeout
from xpra.platform.paths import get_icon_filename, get_icon_dir
from xpra.platform.paths import get_icon_filename
from xpra.notifications.common import parse_image_path
from xpra.server import EXITING_CODE
from xpra.codecs.loader import codec_versions
Expand Down Expand Up @@ -291,13 +290,13 @@ def is_req(mode):

def drop_client(reason="unknown", *args):
self.disconnect_client(proto, reason, *args)
def get_window_id(wid):
return self._window_to_id.get(wid)
get_window_id = self._window_to_id.get
bandwidth_limit = self.get_client_bandwidth_limit(proto)
ClientConnectionClass = self.get_server_source_class()
ss = ClientConnectionClass(proto, drop_client,
self.session_name,
self.idle_add, self.timeout_add, self.source_remove, self.setting_changed,
self.idle_timeout, self.idle_timeout_cb, self.idle_grace_timeout_cb,
self.idle_timeout,
self._socket_dir, self.unix_socket_paths, not is_request, self.dbus_control,
self.get_transient_for, self.get_focus, self.get_cursor_data,
get_window_id,
Expand Down Expand Up @@ -862,36 +861,6 @@ def is_timedout(self, protocol):
return v


def idle_timeout_cb(self, source):
timeoutlog("idle_timeout_cb(%s)", source)
p = source.protocol
if p:
self.disconnect_client(p, IDLE_TIMEOUT)

def idle_grace_timeout_cb(self, source):
timeoutlog("idle_grace_timeout_cb(%s)", source)
nid = XPRA_IDLE_NOTIFICATION_ID
actions = ()
if source.send_notifications_actions:
actions = ("cancel", "Cancel Timeout")
user_icon = os.path.join(get_icon_dir(), "timer.png")
icon = parse_image_path(user_icon) or ()
def idle_notification_action(nid, action_id):
timeoutlog("idle_notification_action(%i, %s)", nid, action_id)
if action_id=="cancel":
source.user_event()
source.no_idle()
if self.session_name!="Xpra":
summary = "The Xpra session %s" % self.session_name
else:
summary = "Xpra session"
summary += " is about to timeout"
body = "Unless this session sees some activity,\n" + \
"it will be terminated soon."
source.notify("", nid, "Xpra", 0, "", summary, body, actions, {}, source.idle_grace_duration*1000, icon, user_callback=idle_notification_action)
source.go_idle()


def _log_disconnect(self, proto, *args):
#skip logging of disconnection events for server sources
#we have tagged during hello ("info_request", "exit_request", etc..)
Expand Down
19 changes: 12 additions & 7 deletions src/xpra/server/source/client_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@
"""
class ClientConnection(AudioMixin, MMAP_Connection, ClipboardConnection, FilePrintMixin, NetworkStateMixin, ClientInfoMixin, DBUS_Mixin, WindowsMixin, EncodingsMixin, IdleMixin, InputMixin, AVSyncMixin, ClientDisplayMixin, WebcamMixin):

def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove, setting_changed,
idle_timeout, idle_timeout_cb, idle_grace_timeout_cb,
def __init__(self, protocol, disconnect_cb, session_name,
idle_add, timeout_add, source_remove, setting_changed,
idle_timeout,
socket_dir, unix_socket_paths, log_disconnect, dbus_control,
get_transient_for, get_focus, get_cursor_data_cb,
get_window_id,
Expand All @@ -81,8 +82,9 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
speaker_codecs, microphone_codecs,
default_quality, default_min_quality,
default_speed, default_min_speed):
log("ServerSource%s", (protocol, disconnect_cb, idle_add, timeout_add, source_remove, setting_changed,
idle_timeout, idle_timeout_cb, idle_grace_timeout_cb,
log("ServerSource%s", (protocol, disconnect_cb, session_name,
idle_add, timeout_add, source_remove, setting_changed,
idle_timeout,
socket_dir, unix_socket_paths, log_disconnect, dbus_control,
get_transient_for, get_focus,
get_window_id,
Expand All @@ -109,7 +111,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
DBUS_Mixin.__init__(self, dbus_control)
WindowsMixin.__init__(self, get_transient_for, get_focus, get_cursor_data_cb, get_window_id, window_filters)
EncodingsMixin.__init__(self, core_encodings, encodings, default_encoding, scaling_control, default_quality, default_min_quality, default_speed, default_min_speed)
IdleMixin.__init__(self, idle_timeout, idle_timeout_cb, idle_grace_timeout_cb)
IdleMixin.__init__(self, idle_timeout)
InputMixin.__init__(self)
AVSyncMixin.__init__(self, av_sync)
ClientDisplayMixin.__init__(self)
Expand All @@ -119,6 +121,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
self.counter = counter.increase()
self.connection_time = monotonic_time()
self.close_event = Event()
self.session_name = session_name

self.protocol = protocol
self.ordinary_packets = []
Expand All @@ -137,7 +140,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
#these statistics are shared by all WindowSource instances:
self.statistics = GlobalPerformanceStatistics()

self.init_vars()
self.init()

# ready for processing:
protocol.set_packet_source(self.next_packet)
Expand All @@ -146,7 +149,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
def __repr__(self):
return "%s(%i : %s)" % (type(self).__name__, self.counter, self.protocol)

def init_vars(self):
def init(self):
self.hello_sent = False
self.info_namespace = False
self.send_notifications = False
Expand All @@ -168,6 +171,8 @@ def init_vars(self):
self.wants_display = True
self.wants_events = False
self.wants_default_cursor = False
for c in ClientConnection.__bases__:
c.init_state(self)


def is_closed(self):
Expand Down
7 changes: 2 additions & 5 deletions src/xpra/server/source/clientdisplay_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@
"""
class ClientDisplayMixin(StubSourceMixin):

def __init__(self):
self.init_vars()

def cleanup(self):
self.init_vars()
self.init_state()

def init_vars(self):
def init_state(self):
self.icc = {}
self.display_icc = {}
self.randr_notify = False
Expand Down
7 changes: 2 additions & 5 deletions src/xpra/server/source/clientinfo_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@
"""
class ClientInfoMixin(StubSourceMixin):

def __init__(self):
self.init_vars()

def cleanup(self):
self.init_vars()
self.init_state()

def init_vars(self):
def init_state(self):
self.uuid = ""
self.machine_id = ""
self.hostname = ""
Expand Down
47 changes: 37 additions & 10 deletions src/xpra/server/source/idle_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from xpra.log import Logger
log = Logger("timeout")

from xpra.util import envint, XPRA_IDLE_NOTIFICATION_ID
from xpra.util import envint, IDLE_TIMEOUT, XPRA_IDLE_NOTIFICATION_ID
from xpra.os_util import monotonic_time
from xpra.server.source.stub_source_mixin import StubSourceMixin

Expand All @@ -16,18 +16,14 @@

class IdleMixin(StubSourceMixin):

def __init__(self, idle_timeout, idle_timeout_cb, idle_grace_timeout_cb):
def __init__(self, idle_timeout):
self.idle_timeout = idle_timeout
self.idle_timeout_cb = idle_timeout_cb
self.idle_grace_timeout_cb = idle_grace_timeout_cb
self.last_user_event = monotonic_time()
#grace duration is at least 10 seconds:
self.idle_grace_duration = max(10, int(self.idle_timeout*(100-GRACE_PERCENT)//100))
self.idle = False
self.idle_timer = None
self.idle_grace_timer = None
self.schedule_idle_grace_timeout()
self.schedule_idle_timeout()

def cleanup(self):
self.cancel_idle_grace_timeout()
Expand All @@ -40,6 +36,12 @@ def get_info(self):
}


def parse_client_caps(self, _c):
#start the timer
log.warn("parse_client_caps idle")
self.schedule_idle_grace_timeout()
self.schedule_idle_timeout()

def user_event(self):
log("user_event()")
self.last_user_event = monotonic_time()
Expand Down Expand Up @@ -82,12 +84,37 @@ def schedule_idle_grace_timeout(self):

def idle_grace_timedout(self):
self.idle_grace_timer = None
log("idle_grace_timedout() callback=%s", self.idle_grace_timeout_cb)
self.idle_grace_timeout_cb(self)
log("idle_grace_timedout()")
if not self.send_notifications:
#not much we can do!
return
#notify the user, giving him a chance to cancel the timeout:
nid = XPRA_IDLE_NOTIFICATION_ID
if nid in self.notification_callbacks:
return
actions = ()
if self.send_notifications_actions:
actions = ("cancel", "Cancel Timeout")
if self.session_name!="Xpra":
summary = "The Xpra session %s" % self.session_name
else:
summary = "Xpra session"
summary += " is about to timeout"
body = "Unless this session sees some activity,\n" + \
"it will be terminated soon."
self.may_notify(nid, summary, body, actions, {}, expire_timeout=10*1000, icon_name="timer", user_callback=self.idle_notification_action)
self.go_idle()

def idle_notification_action(self, nid, action_id):
log("idle_notification_action(%i, %s)", nid, action_id)
if action_id=="cancel":
self.user_event()

def idle_timedout(self):
self.idle_timer = None
log("idle_timedout() callback=%s", self.idle_timeout_cb)
self.idle_timeout_cb(self)
p = self.protocol
log("idle_timedout() protocol=%s", p)
if p:
self.disconnect(IDLE_TIMEOUT)
if not self.is_closed():
self.schedule_idle_timeout()
3 changes: 3 additions & 0 deletions src/xpra/server/source/stub_source_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

class StubSourceMixin(object):

def init_state(self):
pass

def cleanup(self):
pass

Expand Down

0 comments on commit d576049

Please sign in to comment.