Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> остановка XMLRPC сервера 
V
    Опции темы
@lex
Дата 16.10.2006, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 3.2.2004
Где: Москва

Репутация: нет
Всего: нет



есть SimpleXMLRPCServer 
он запускается в отдельном Thread
проблема в том что я не доконца понимаю
какие действия надо выполнить чтобы его "грамотно" остановить - тобишь освободить сокеты

код:

Код

import SimpleXMLRPCServer

#from Configurator import configurator
#from HostManager import hostManager
#from MediaLibrary import mediaLibrary
#from VirtualPlayersManager import vPlayersManager

import threading,select,socket,time,xmlrpclib


class DebugXMLRPCInstance:
        
        def exposed(func):
            func.exposed=True
            return func

        def _isPublic(self,method):
            try:
                func = getattr(self,method)
                #check if func is exposed
                exposedFlag = getattr(func,'exposed')
                if not exposedFlag: raise AttributeError
            except AttributeError:
                return False
            else:
                return True

        @exposed
        def eval(self,expr):
            res=eval(expr)
            print "res=",res
            return res

        def _listMethods(self):
            return filter(self._isPublic,dir(self))

        def _dispatch(self, method, params):
            try:
                # We are forcing the 'export_' prefix on methods that are
                # callable through XML-RPC to prevent potential security
                # problems
                #if method in list
                print "try dispatch ",method,params
                func = getattr(self, method)
                exposedFlag = getattr(func,'exposed')
                if not exposedFlag: raise AttributeError

            except AttributeError:
                raise Exception('method "%s" is not supported' % method)
            else:
                return func(*params)
   

class DebugXMLRPCServerThread(threading.Thread):

    def __init__(self,serverAddr):
        self.serverAddr=serverAddr
        threading.Thread.__init__(self)

    def run(self):
        server=SimpleXMLRPCServer.SimpleXMLRPCServer(self.serverAddr)        
        server.register_instance(DebugXMLRPCInstance())

        self.needServe=True
        print "starting server"
        while self.needServe:
            server.handle_request()
        print "try cleanup"
        time.sleep(.5)
        server.server_close()
        print "cleanuped"

    def stop_serve(self):
        self.needServe=False
        try:
            sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            sock.connect(self.serverAddr)
            sock.send("By")
            sock.close()
        except:
            pass
#        srv=xmlrpclib.ServerProxy('http://localhost:%d'%self.serverAddr[1])
#        srv.stopServe()

if __name__=='__main__':
    serverAddr=('',8080,)
    server=DebugXMLRPCServerThread(serverAddr)
    server.start()
    try:
        while 1:
            time.sleep(1)
            print time.asctime()
            print threading.enumerate()

    except KeyboardInterrupt:
        server.stop_serve()
        server.join()


так-то он всё конечно работает 
Цитата

py4 DebugXMLRPCServer.py
starting server
Mon Oct 16 15:32:55 2006
[<_MainThread(MainThread, started)>, <DebugXMLRPCServerThread(Thread-1, started)>]
Mon Oct 16 15:32:56 2006
[<_MainThread(MainThread, started)>, <DebugXMLRPCServerThread(Thread-1, started)>]
Mon Oct 16 15:32:57 2006
[<_MainThread(MainThread, started)>, <DebugXMLRPCServerThread(Thread-1, started)>]
[<_MainThread(MainThread, started)>, <DebugXMLRPCServerThread(Thread-1, started)>]
localhost - - [16/Oct/2006 15:32:58] code 400, message Bad request syntax ('By')
localhost - - [16/Oct/2006 15:32:58] "By" 400 -
try cleanup
cleanuped
[<_MainThread(MainThread, started)>]
avalon% netstat -anop|grep 8080
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)


как видим все сокеты отмираеют всё ок

теперь тест:

1-ый 
Код

import unittest
import DebugXMLRPCServer
import xmlrpclib,threading
import time

class TestDebugXMLRPCServer(unittest.TestCase):

    DEBUG_XMLRPC_SERVER_ADDR=('',60000)

    def setUp(self):
        self.dServer=DebugXMLRPCServer.DebugXMLRPCServerThread(self.DEBUG_XMLRPC_SERVER_ADDR)
        self.dServer.start()

    def tearDown(self):
        self.dServer.stop_serve()
        self.dServer.join()

    def testStartStop(self):
        time.sleep(1)

if __name__=='__main__':
    suite = unittest.makeSuite(TestDebugXMLRPCServer)
    unittest.TextTestRunner(verbosity=2).run(suite)

так вобщем тоже...

а  вот если добавить обращение к нему 
Код

    def testEval(self):
        srv=xmlrpclib.ServerProxy("http://localhost:%d"%self.DEBUG_XMLRPC_SERVER_ADDR[1])
        self.assertEqual(4,dsrv.eval('2+2'))


он вот отработает но :
Цитата

.....
testStartStop (__main__.TestDebugXMLRPCServer) ... try start
[<_MainThread(MainThread, started)>, <DebugXMLRPCServerThread(Thread-2, started)>]
Exception in thread Thread-2:
Traceback (most recent call last):
  File "threading.py", line 442, in __bootstrap
    self.run()
  File "/home/wizard/progs/csXMLRPCSystem/DebugXMLRPCServer.py", line 84, in run
    server=SimpleXMLRPCServer.SimpleXMLRPCServer(self.serverAddr)
  File "SimpleXMLRPCServer.py", line 473, in __init__
    SocketServer.TCPServer.__init__(self, addr, requestHandler)
  File "SocketServer.py", line 330, in __init__
    self.server_bind()
  File "SocketServer.py", line 341, in server_bind
    self.socket.bind(self.server_address)
  File "<string>", line 1, in bind
error: (98, 'Address already in use')


netstat:
Цитата

netstat -anop|grep 60000
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.1:60000         127.0.0.1:46615         TIME_WAIT  -                   timewait (24,30/0/0)


timewait ~ минуты

честно говоря совершенно не пойму почему. Может кто объяснит  smile 




PM MAIL ICQ   Вверх
@lex
Дата 16.10.2006, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 3.2.2004
Где: Москва

Репутация: нет
Всего: нет



Что интересно аналогичные манипуляции с SocketServer.TCPThreadingServer 
проходят вполне успешно.
Следовательно всё дело в xmlrpclib.ServerProxy
тобишь в этом тесте:
Код

def testEval(self):
        srv=xmlrpclib.ServerProxy("http://localhost:%d"%self.DEBUG_XMLRPC_SERVER_ADDR[1])
        self.assertEqual(4,dsrv.eval('2+2'))

мда....


PM MAIL ICQ   Вверх
@lex
Дата 17.10.2006, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 3.2.2004
Где: Москва

Репутация: нет
Всего: нет



вопрос решился 
оказывается для того чтобы избавиться от "проблемы" TIMEWAIT состяния сокета
нужно проставить ему опцию 
Код

socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

впринципе эта проблема не нова и у SimpleXMLRPCServer как наследника SocketServer.TCPServer
есть флаг allow_reuse_address
создаём собственны SimpleXMLRPCServer
в конструкторе устанавливаем этот флаг(перед вызовом родительского __init__) и радуемся жизни:
Код

class DebugXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):

    def __init__(self,server_address):
        self.allow_reuse_address=True
        SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self,server_address)
        self.needServe=True

    def start_serve(self):
        while self.needServe:
            self.handle_request()

    def stop_serve(self):
        self.needServe=False
        try:
            sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            sock.connect(self.server_address)
            sock.send("By")
            sock.close()
        except:
            pass


подробности jj > ru_python

Это сообщение отредактировал(а) @lex - 17.10.2006, 10:23
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1138 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.