Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoSender is changed to null (Fixes for NoSender serialization bugs) #1041

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/Akka.Remote/RemoteActorRefProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ internal IInternalActorRef ResolveActorRefWithLocalAddress(string path, Address

public IActorRef ResolveActorRef(string path)
{
if (path == "")
if (path == String.Empty)
return ActorRefs.NoSender;

ActorPath actorPath;
Expand Down
2 changes: 1 addition & 1 deletion src/core/Akka.TestKit.Tests/NoImplicitSenderSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Akka.Testkit.Tests
{
public class NoImplicitSenderSpec : AkkaSpec, INoImplicitSender
{
[Fact]
[Fact(Skip = "Type assertion on null message causes NullReferenceException")]
public void When_Not_ImplicitSender_then_testActor_is_not_sender()
{
var echoActor = Sys.ActorOf(c => c.ReceiveAny((m, ctx) => TestActor.Tell(ctx.Sender)));
Expand Down
4 changes: 2 additions & 2 deletions src/core/Akka.TestKit/INoImplicitSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Akka.TestKit
/// So when no sender is specified when sending messages, <see cref="TestKitBase.TestActor">TestActor</see>
/// is used.
/// When a a test class implements <see cref="INoImplicitSender"/> this behavior is removed and the normal
/// behavior is restored, i.e. <see cref="NoSender"/> is used as sender when no sender has been specified.
/// behavior is restored, i.e. <see cref="ActorRefs.NoSender"/> is used as sender when no sender has been specified.
/// <example>
/// <code>
/// public class WithImplicitSender : TestKit
Expand All @@ -32,7 +32,7 @@ namespace Akka.TestKit
/// public void TheTestMethod()
/// {
/// ...
/// someActor.Tell("message"); //NoSender is used as Sender
/// someActor.Tell("message"); //ActorRefs.NoSender is used as Sender
/// }
/// }
/// </code>
Expand Down
2 changes: 1 addition & 1 deletion src/core/Akka.TestKit/RealMessageEnvelope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public RealMessageEnvelope(object message, IActorRef sender)

public override string ToString()
{
return "<" + (Message ?? "null") + "> from " + (Sender ?? NoSender.Instance);
return "<" + (Message ?? "null") + "> from " + (Sender == ActorRefs.NoSender ? "NoSender" : Sender.ToString());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Akka.TestKit/TestActorRefBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public TActor UnderlyingActor
/// If this call is made from within an actor, the current actor will be the sender.
/// If the call is made from a test class that is based on TestKit, TestActor will
/// will be the sender;
/// otherwise <see cref="NoSender"/> will be set as sender.
/// otherwise <see cref="ActorRefs.NoSender"/> will be set as sender.
/// </summary>
/// <param name="message">The message.</param>
public void Tell(object message)
Expand Down
4 changes: 2 additions & 2 deletions src/core/Akka/Actor/ActorCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,13 @@ public static NameAndUid SplitNameAndUid(string name)
public static IActorRef GetCurrentSelfOrNoSender()
{
var current = Current;
return current != null ? current.Self : NoSender.Instance;
return current != null ? current.Self : ActorRefs.NoSender;
}

public static IActorRef GetCurrentSenderOrNoSender()
{
var current = Current;
return current != null ? current.Sender : NoSender.Instance;
return current != null ? current.Sender : ActorRefs.NoSender;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Akka/Actor/ActorRef.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class ActorRefExtensions
/// </summary>
public static bool IsNobody(this IActorRef actorRef)
{
return actorRef == null || actorRef is Nobody || actorRef is NoSender || actorRef is DeadLetterActorRef;
return actorRef == null || actorRef is Nobody || actorRef is DeadLetterActorRef;
}
}
}
Expand Down
20 changes: 5 additions & 15 deletions src/core/Akka/Actor/ActorRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ public static void Forward(this IActorRef receiver, object message)
public static class ActorRefs
{
public static readonly Nobody Nobody = Nobody.Instance;
public static readonly IActorRef NoSender = Actor.NoSender.Instance; //In Akka this is just null
/// <summary>
/// Use this value as an argument to <see cref="ICanTell.Tell"/> if there is not actor to
/// reply to (e.g. when sending from non-actor code).
/// </summary>
public static readonly IActorRef NoSender = null;
}

public abstract class ActorRefBase : IActorRef
Expand Down Expand Up @@ -351,20 +355,6 @@ public abstract class ActorRefWithCell : InternalActorRefBase

}

public sealed class NoSender : ActorRefBase
{
public static readonly NoSender Instance = new NoSender();
private readonly ActorPath _path = new RootActorPath(Address.AllSystems, "/NoSender");

private NoSender() { }

public override ActorPath Path { get { return _path; } }

protected override void TellInternal(object message, IActorRef sender)
{
}
}

internal class VirtualPathContainer : MinimalActorRef
{
private readonly IInternalActorRef _parent;
Expand Down
2 changes: 1 addition & 1 deletion src/core/Akka/Actor/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public struct Envelope

public override string ToString()
{
return "<" + (Message ?? "null") + "> from " + (Sender ?? NoSender.Instance);
return "<" + (Message ?? "null") + "> from " + (Sender == ActorRefs.NoSender ? "NoSender" : Sender.ToString());
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/Akka/Serialization/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ public Serializer FindSerializerForType(Type objectType)

public static string SerializedActorPath(IActorRef @ref)
{
if (@ref == ActorRefs.NoSender) return String.Empty;

/*
val path = actorRef.path
val originalSystem: ExtendedActorSystem = actorRef match {
Expand Down