远程代码的执行和更新

# rcode.py

# -*- coding: utf-8 -*-
import logging

log = logging.getLogger(__name__)


class Code(object):
    def __init__(self, had_changed=False, obj=None):
        self.obj = obj
        self.had_changed = had_changed


class CodeManager(object):
    def __init__(self, redis=None, prefix="__code__"):
        self.redis_client = redis
        self.prefix = prefix

        self.__code_obj = {}

    def update(self, name, had_changed=True):
        if name in self.__code_obj:
            self.__code_obj[name].had_changed = had_changed

    def package(self, name):
        return self.__package(name)

    def remove(self, name):
        if '#' in name:
            try:
                del self.__code_obj[name]
            except Exception, e:
                log.error(e.message)

        else:
            for key in self.__code_obj.keys():
                if key.startswith(name):
                    try:
                        del self.__code_obj[key]
                    except Exception, e:
                        log.error(e.message)

    def __package(self, name):
        c = self.__code_obj.get(name)
        if c and not c.had_changed:
            return c.obj

        p, n = name.split("#")
        __s = self.redis_client.conn().hget("{}.{}".format(self.prefix, p), n)
        if not __s:
            log.error(u"{} 不存在".format(name))
            return

        _obj = self.__e(name.split(".").pop(), __s)
        if not _obj:
            return

        self.__code_obj[name] = Code(obj=_obj)
        return _obj

    def __e(self, name, source):
        try:
            exec source
            __c = eval(name)
            setattr(__c, "package", self.__package)
            return __c
        except Exception, e:
            log.error(e.message)
posted @ 2017-05-27 15:22  白云辉  阅读(271)  评论(0编辑  收藏  举报