orleans icon indicating copy to clipboard operation
orleans copied to clipboard

Multiple activations of same grain

Open mradovcic opened this issue 3 years ago • 4 comments

Hi all,

I have an issue where multiple activations of same grain are activated even when there is only one silo in the cluster Grain code is here

    public interface IActivityLookupGrain : IGrainWithStringKey
    {
        [AlwaysInterleave]
        Task<Guid?> GetSubscribedUser();

        Task SubscribeUser(Guid userId);
        Task UnsubscribeUser(Guid userId);
        Task Deactivate();
    }
    [PreferLocalPlacement]
    public class ActivityLookupGrain : Grain, IActivityLookupGrain
    {
        private Guid? State;

        public ActivityLookupGrain()
        {
            State = null;
        }

        public override async Task OnActivateAsync()
        {
            Console.WriteLine($"Activating ActivityLookupGrain {this.GetPrimaryKeyString()} {DateTime.UtcNow}");
            this.DelayDeactivation(TimeSpan.MaxValue);
            await base.OnActivateAsync();
        }

        public override Task OnDeactivateAsync()
        {
           Console.WriteLine($"Dectivating ActivityLookupGrain {this.GetPrimaryKeyString()} {DateTime.UtcNow}");
            return base.OnDeactivateAsync();
        }

        public Task<Guid?> GetSubscribedUser()
        {
            Console.WriteLine($"GetSubscribedUser ActivityLookupGrain {this.GetPrimaryKeyString()} {DateTime.UtcNow}");
            return Task.FromResult(State);
        }

        public Task SubscribeUser(Guid userId)
        {
            Console.WriteLine($"SubscribeUser ActivityLookupGrain {this.GetPrimaryKeyString()} {DateTime.UtcNow}");
            State = userId;
            return Task.CompletedTask;
        }

        public Task UnsubscribeUser(Guid userId)
        {
            if (State.GetValueOrDefault() == userId)
                State = null;
            return Task.CompletedTask;
        }

        public Task Deactivate()
        {
            Console.WriteLine($"Deactivate ActivityLookupGrain {this.GetPrimaryKeyString()} {DateTime.UtcNow}");
            this.DeactivateOnIdle();
            return Task.CompletedTask;
        }
    }

it is a very simple grain that is used only to follow which user (if any) is subscribed to follow changes that are sent as notifications from other grain.

// UserGrain    

public async Task NotificationSubscribe(Guid id1, Guid id2, Guid id3)
{
	var key = KeyHelper.ConstructKey(id1, id2, id3); // $"{id1}_{id2}_{id3}
	await GrainFactory.GetGrain<IActivityLookupGrain>(key).SubscribeUser(this.GetPrimaryKey());
	await GrainFactory.GetGrain<IWorkerGrain>(key).Initialize();
}

//WorkerGrain
public async Task Initialize()
{
	//...some logic...
	var key = this.GetPrimaryKeyString();
	string notificationUserId = (await GrainFactory.GetGrain<IActivityLookupGrain>(key).GetSubscribedUser()).ToString();
	if (String.IsNullOrEmpty(notificationUserId))
	{
		_logger.WriteWarning("Activity lookup grain - Empty userId.");
		return;
	}
	//...send init success notification
}

And this is what i get in a console

Activating ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:07 PM
SubscribeUser ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:07 PM
Activating ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:08 PM
GetSubscribedUser ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:08 PM
Activating ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:14 PM
GetSubscribedUser ActivityLookupGrain 679a5ac9-d5da-4c9e-9dd2-dcf2eb07cdbc_bd4439af-29c3-2fdb-ed40-78fe07f61215_f73fd581-a23c-40b5-b9b9-ba43ddfa1818 5/17/2021 4:35:14 PM

Also "Activity lookup grain - Empty userId" is logged None of the grains are stateless workers and all my other grains show up correctly in orleans dashboard but ActivityLookupGrain never shows up

Orleans packages are version 3.3.0 and application is built with netCore 3.1 Any suggestions would be really helpful

mradovcic avatar May 17 '21 16:05 mradovcic

Do you have a repro somewhere? How do you configure your silos?

benjaminpetit avatar May 24 '21 22:05 benjaminpetit

I sometimes have this problem too, I deploy in Kubernetes, and this problem occurs when updating the program

qzwzqty avatar May 28 '21 05:05 qzwzqty

@mradovcic @qzwzqty were you able to find a solution?

cove avatar Oct 02 '21 18:10 cove

We've moved this issue to the Backlog. This means that it is not going to be worked on for the coming release. We review items in the backlog at the end of each milestone/release and depending on the team's priority we may reconsider this issue for the following milestone.

ghost avatar Jul 28 '22 23:07 ghost