# -*- coding: utf-8 -*- # Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import os import glob import sys import time import datetime import pickle from calculate.core.datavars import DataVarsCore from calculate.core.server.core_interfaces import CoreServiceInterface from calculate.lib.cl_lang import setLocalTranslate _ = lambda x: x setLocalTranslate('cl_core3', sys.modules[__name__]) def clean(sid_file, pid_file, sid_pid, sids_dir, pids_dir): """ Удалить все файлы сервера после перезапуска """ for fn in (sid_file, pid_file, sid_pid): if os.path.exists(fn): try: os.unlink(fn) except OSError: pass for dn in (sids_dir, pids_dir): if os.path.isdir(dn): for filename in glob.glob(os.path.join(dn, "*.sid")): try: os.unlink(filename) except OSError: pass class CoreWsdl(CoreServiceInterface): # watch for process @staticmethod def watcher_pid_proc(cls, sid, pid): period = 2 time.sleep(period) try: # while process status "Active" while cls.glob_process_dict[pid]['status'] == 1: # frequency check time.sleep(period) cls.delete_pid(cls, sid, pid) except IOError as e: print('Except IOError', str(e)) except Exception: print(_("PID %d watcher error") % pid) try: cls.delete_pid(cls, sid, pid) except Exception: pass time.sleep(0.1) @staticmethod def delete_pid(cls, sid, pid): while len(cls.glob_frame_list[pid]) > \ cls.glob_process_dict[pid]['counter']: time.sleep(1) methodname = cls.glob_process_dict[pid]['method_name'] if methodname: cls.clear_cache(sid, methodname) cls.del_pid(cls, pid) cls.del_pid_from_sid_pid(cls, pid) def monitor(certbase, sid_file): """ function to delete old session """ # Get value of period and lifetime session from DataVars try: ob = DataVarsCore() ob.importCore() if not ob.flIniFile(): sys.exit(1) period = float(ob.Get('cl_core_monitor_period')) sid_live = float(ob.Get('cl_core_sid_live')) except Exception: print(_("Variable cl_core_monitor_period or cl_core_sid_live not " "found")) raise # Check lifetime. if necessary, remove while True: # check session try: sid_file_t = sid_file + '_temp' fd = open(sid_file, 'r') ft = open(sid_file_t, 'w') while 1: try: # read all on one record list_sid = pickle.load(fd) except (EOFError, KeyError, IOError): break # how time exists session delta = datetime.datetime.now() - list_sid[2] # if not outdated, then leave if delta.seconds < sid_live * 60: pickle.dump(list_sid, ft) fd.close() ft.close() # copy all from temp file ft = open(sid_file_t, 'rb') fd = open(sid_file, 'wb') ft.seek(0) fd.write(ft.read()) ft.close() fd.close() # Delete temp file os.unlink(sid_file_t) except (IOError, OSError): return 1 # Частота проверки time.sleep(60 * period) # check client's presence def sid_monitor(sid_fn, sids_dn, cls): # check interval period = 21 while True: try: sids = [] # create, if file not exists if not os.path.exists(sid_fn): temp = open(sid_fn, 'w') temp.close() fd = open(sid_fn, 'r') while 1: try: # read all on one record list_sid = pickle.load(fd) except (EOFError, KeyError, IOError): break # add session id in sesession list sids.append(list_sid[0]) fd.close() except (IOError, OSError): print(_("Error reading SID files")) return try: # for each session for filename in sids: # find file this session sid_path = sids_dn + "/%d.sid" % filename with cls.sid_locker: if os.path.isfile(sid_path): with open(sid_path) as fd: # read information about session sid_inf = pickle.load(fd) # if number of missed inspections more 3 if sid_inf[1] > 3: # flag client absence sid_inf[2] = 1 fd.close() if os.path.isfile(sid_path): # add to digit missed inspections # client constantly nulls this value! ft = open(sid_path, 'w') if sid_inf[1] < 4: sid_inf[1] += 1 pickle.dump(sid_inf, ft) ft.close() except (IOError, OSError, KeyError): pass # check period time.sleep(period)