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

An item with the same key has already been added. Key: stm #133

Closed
jahanbinali1988 opened this issue Nov 8, 2023 · 1 comment
Closed

Comments

@jahanbinali1988
Copy link

Describe the bug
I am using the "snowplow.tracker" Nuget package in my dotnet core project. when I deployed my code on the server with the container, my server restarted every 2 minutes with the following error.

Occurred exception
Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: stm
at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.AddSendTimestamp(List1 payloadList) at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.SendPostAsync(List1 itemList)
at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.Send(List`1 itemList)
at Snowplow.Tracker.Emitters.AsyncEmitter.loop()

Additional context

public class SnowplowService : ISnowplowService
{
private readonly SnowplowConfig _configuration;
private readonly ILogger _logger;

public SnowplowService(IOptions<SnowplowConfig> configuration,
    ILogger<SnowplowService> logger)
{
    this._configuration = configuration.Value;
    this._logger = logger;
}

public async Task<SnowplowResponse> SendEvent(SnowplowRequest request)
{
    var response = new SnowplowResponse();
    var tracker = Tracker.Instance;            
    var logger = new ConsoleLogger();
    var endpoint = new SnowplowHttpCollectorEndpoint
        (host: _configuration.BaseAddress, port: _configuration.Port, l: logger,
        method: Snowplow.Tracker.Endpoints.HttpMethod.POST, protocol: HttpProtocol.HTTP);

    try
    {
        var queue = new InMemoryBlockingQueue();
        var emitter = new AsyncEmitter(endpoint, queue, l: logger);
        var subject = new Subject().SetPlatform(Platform.Srv).SetLang(_configuration.Language);

        if (tracker.Started == false)
        {
            tracker.Start(
                emitter: emitter,
                subject: subject,
                trackerNamespace: _configuration.TrackerNamespace,
                appId: _configuration.AppId,
                encodeBase64: false,
                l: logger);
        }

        if (tracker.Started)
        {
            var dataKeyValues = new Dictionary<string, object>
            {
                { "userId", request.UserId! },
                { "eventName", request.EventName },
                { "eventTime", request.EventTime },
                { "eventData", Utility.ConvertToDictionaryObject(request: request.EventData) }
            };
            
            var eventKeyValues = new Dictionary<string, object>()
            {
                { "vendor", _configuration.Vendor! },
                { "model", request.SnowplowRequestName!},
            };

            var eventData = new SelfDescribingJson
                ($"iglu:{_configuration.Vendor}/{request.SnowplowRequestName!}/jsonschema/1-0-0", dataKeyValues);

            var requestItem = new List<IContext>();

            var context = new GenericContext()
                .SetSchema($"iglu:com.vendor/meta/jsonschema/1-0-0")
                .AddDict(eventKeyValues)
                .Build();

            requestItem.Add(item: context);

            var trackingItem =
                new SelfDescribing()
                .SetEventData(eventData: eventData)
                .SetCustomContext(customContexts: requestItem)
                .Build();
            
            tracker.Track(newEvent: trackingItem);
        }

        response = new SnowplowResponse(true, "");
    }
    catch (Exception ex)
    {
        response = new SnowplowResponse(false, ex.Message);
    }

    return response;
}

}

	internal static Dictionary<string, object> ConvertToDictionaryObject<T>(T request) where T : class
	{
		var result = new Dictionary<string, object>();

		var properties = request.GetType().GetProperties();

		foreach (var item in properties)
		{
			var key = item.Name.ToLower().Trim();

			var value = item.GetValue(request);

			if (result.ContainsKey(key) == false)
				result.Add(key: key, value: value!);
		}

		return result;
	}
@matus-tomlein
Copy link
Contributor

Thanks for the bug report @jahanbinali1988 and sorry for the late answer. We will look into this shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants