0

私はPythonで書かれたLaunchDaemonを持っており、root権限で長くてリソースを大量に消費するバックグラウンドタスクを実行します。それが機能するので、複数のGUIエージェント(ログインしたユーザーごとに1つ)にステータス更新を送信する必要があり、適切なIPCメカニズムを見つけるのに苦労しています。デーモンとエージェントは異なるブートストラップコンテキストで実行されるため、共有オブジェクトは機能しません。デーモンにソケットを開かせることはできません。デーモンは長期間応答できず、クライアントは更新をポーリングする必要があるためです。私が思いついた最善の方法は、各エージェントが独自のソケットを開き、デーモンが順番に各ソケットに書き込むことですが、それはせいぜいエレガントではないようです。他に選択肢はありますか?ああ、それはMac OSX10.5以降で動作する必要があります。

4

1 に答える 1

0

最終的に、各 GUI エージェントが /tmp の下にデータグラム ソケットを作成し、launchdaemon がメッセージをそれぞれに順番に送信し、古いソケットをクリーンアップします。

SOCKET_DIR = "/tmp"
SOCKET_NAME = "se.gu.it.dafgu_migration_status"

status_socket = None

def set_status_menu(status, message):
    global status_socket
    try:
        if status_socket is None:
            status_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        if status_socket is not None:
            message = serializePlist({
                "DAFGUMigrationStatus": status,
                "DAFGUMigrationMessage": message,
            })
            for item in os.listdir(SOCKET_DIR):
                if item.startswith(SOCKET_NAME):
                    socket_path = os.path.join(SOCKET_DIR, item)
                    logging.debug("Sending message to %s" % socket_path)
                    try:
                        status_socket.sendto(message, socket_path)
                    except socket.error, e:
                        if e[0] == errno.ECONNREFUSED:
                            logging.info("Removing stale socket %s" % socket_path)
                            os.unlink(socket_path)
                        else:
                            logging.warn("Sending to %s failed: %s" % (socket_path, e))
    except BaseException, e:
        logging.debug("Unhandled exception when updating status menu: %s" % e)

完全な実装は github で見つけることができます:

于 2012-11-19T09:19:32.710 に答える