2

まず、私はScalaを初めて使用します。

私はScalaでロギング機能を作成しています。これは、Actorクラスを拡張するクラスにすぎません。このようにして、ユーザーはこのクラスを拡張するだけで、ロギング機能を利用できるようになります。基本的に、このクラスを拡張するアクターがメッセージを送受信するたびに、ログファイルに書き込みたいと思います。明確にするために、すべてのアクターには、後で照合できる独自のログファイルがあります。私はランポートクロックスタイルのアプローチを採用して、各アクター(このクラスを拡張する)にメッセージの送受信で更新される独自の時間変数を持たせ、アクターが現在の時間変数(単に正の整数)を比較するようにします。 )送信者と一緒に、その時間変数を2つのうち大きい方で更新します。

今のところ私はそれを次のような単純な方法にすることを選びました

sendMessage(recipient, message)

メッセージ送信用。これは、アクターがXにメッセージを送信しようとしているファイルにログを記録するだけです。

今、私が困惑しているのは、メッセージを受信するときにロギングを行うことです。アクターがメッセージを受け取ったら、このイベントを次のような形式でログに記録したいだけです。

myLogFile.writeLine(self.ToString+": Got a message from "+X+" at time: "+messageSendTime+", processed the message at" +Math.max(myCurrTime+1, messageSendTime+1))

ただし、誰がこのメッセージを送信したかを知る必要があります。ただし、ユーザーにこの情報(つまり、送信者の名前、時間変数など)をメッセージ自体に含めるように強制しない限り、メッセージ自体は難しくなります。実際の送信者の参照を取得する方法はありますか?これをリモートアクターでも機能させたいです。私が考えることができる唯一の方法は、ユーザーがクラスで定義するactメソッドに、次のような追加のcaseステートメントを追加する場合です。

def act {
    case => // the user's case statements
    ...

    //somehow I append these statements to the end for the Logger class's use
    case (LoggerClassRegisterInboundMessage, message, timeStamp)
        InboundMessagesMap.put(timeStamp, message)
}

この機能を使用することで、ユーザーがメッセージを送信するたびにこれらの非表示のメッセージが送信される「舞台裏」ですべてのロギングを実行できます。ただし、これは、送信者がログ機能も使用している場合にのみ機能します。したがって、より一般的な質問は次のとおりです。送信者のクラスに関係なく、Scalaで送信者の名前/toStringを取得する方法はありますか?

私は実際、メッセージを送信するすべてのクラスがLoggerクラスを拡張するという仮定で問題ありません。ですから、上記の例のような行為に追加する方法を誰かが知っているなら、私も同様に感謝します!

4

1 に答える 1

1

コメントで言われたように、Akkaは行く方法です。とにかく2.10で非推奨になる現在のScalaActorAPIよりもはるかに強力です。

しかし、特定の問題を攻撃するために、これと同様の方法で、ロギングをサポートするアクターの特性を作成できます(これが実際に機能するかどうかはわかりませんが、試すことができます)。

trait LoggingActor extends Actor {
    override def receive[R](pf: PartialFunction[Any, R]): R = {
        //we are appending to the partial function pf a case to handle messages with logging:
        val loggingPf = pf orElse {
            case (LoggerClassRegisterInboundMessage, message, timeStamp) => {
                //do somthing with this log message.
                message //returning the unwrapped result afterwards
            }
        }
        super.receive(loggingPf)
    }

    //overriding the send as well
    override def !(msg: Any): Unit {
        //Wrap it in a logging message
        super ! (LoggerClassRegisterInboundMessage, msg, getTimestamp())
    }
}

そして、次のようなものでアクターを作成します。

val myActor = new MyActor with LoggingActor

それが役に立てば幸い !

于 2012-11-15T13:16:42.667 に答える