Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Simon Dingley 1470 posts 3427 karma points c-trib
    Feb 11, 2016 @ 13:10
    Simon Dingley
    0

    Duplicate Items in Load Balanced Setup

    Hi Richard,

    I have a customer that has a number of regular imports running on an hourly schedule. Occasionally and for no apparent reason we end up with duplicated items being imported. This happened yesterday and the time difference between the two items being created was literally 3/4 seconds.

    My first thought was that perhaps the same import was running on two schedules but that doesn't appear to be the case which makes me ask the question about how the task scheduler behaves in a load balanced environment? Is it possible this task is kicked off on both servers and there is then a race condition problem?

    Thanks, Simon

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Feb 24, 2016 @ 09:09
    Richard Soeteman
    0

    Hi Simon,

    The scheduler was configured on both servers I guess. Best to enable the scheduler only on one instance in the load balanced setup.

    Just remove the cmsimportscheduler module from web.config.

    Hope this helps,

    Richard

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Feb 24, 2016 @ 09:23
    Simon Dingley
    0

    The web.config is sync'd between servers which unfortunately means this is not an option. It needs to be sync'd to ensure the config is identical on all servers behind the load balancer.

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Feb 24, 2016 @ 09:42
    Richard Soeteman
    0

    Hmm then there is no real solution I'm affraid. You could cancel each the importing events on the servers that are not allowed to run the import but that is not an ideal solution. Is it for the same import you need the proxy on? Maybe only allow one server to access that proxy?

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Mar 11, 2016 @ 12:56
    Simon Dingley
    0

    Hi Richard,

    I've looked at BulkImportEventArgs and ImportEventArgs and both contain only the State and no option to cancel the import so it seems that it can't be cancelled via the Importing or BulkImporting events?

    Is the RecordImporting event the only way to cancel the imports? This seems a bit inefficient having to do it for every record on an import process that runs hourly.

    Thanks, Simon

  • Simon Dingley 1470 posts 3427 karma points c-trib
    May 17, 2016 @ 11:43
    Simon Dingley
    0

    For Umbraco v7.2.4+ here is an event handler I will be using to cancel the import if it is running from a slave server in a load balanced setup:

    /// <summary>
    /// Handles the RecordImporting event of the CmsImport control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="CMSImport.Extensions.Providers.ImportProviders.EventArgs.RecordImportingEventArgs"/> instance containing the event data.</param>
    void CmsImport_RecordImporting(object sender, CMSImport.Extensions.Providers.ImportProviders.EventArgs.RecordImportingEventArgs e)
    {
        // Get the current server role using the new features added in 7.2.4
        var serverRole = UmbracoContext.Current.Application.Services.ServerRegistrationService.GetCurrentServerRole();
    
        if (serverRole != ServerRole.Single && serverRole != ServerRole.Master)
        {
            e.Cancel = true;
            global::Umbraco.Core.Logging.LogHelper.Info<EventHandlers>("CMS Import Record Import Cancelled As Calling Server is not Master");
        }
    }
    
  • Simon Dingley 1470 posts 3427 karma points c-trib
    Feb 24, 2016 @ 10:00
    Simon Dingley
    0

    Yes it's the same site. I'm wondering if it is possible to use the new load balancing features to check that the server is the master and not a slave and prevent them being run on slave servers?

    Just having a quick poke around in the Core and they appear to check like this:

    switch (_appContext.GetCurrentServerRole())
    {
        case ServerRole.Slave:
            LogHelper.Debug<ScheduledTasks>("Does not run on slave servers.");
            return true; // DO repeat, server role can change
        case ServerRole.Unknown:
            LogHelper.Debug<ScheduledTasks>("Does not run on servers with unknown role.");
            return true; // DO repeat, server role can change
    }
    
    // ensure we do not run if not main domain, but do NOT lock it
    if (_appContext.MainDom.IsMainDom == false)
    {
        LogHelper.Debug<ScheduledTasks>("Does not run if not MainDom.");
        return false; // do NOT repeat, going down
    }
    
  • Richard Soeteman 4035 posts 12842 karma points MVP
    Feb 24, 2016 @ 10:04
    Richard Soeteman
    0

    Yeah would be possible if CMSImport only supported those versions but it's also supported on V6 and that is an issue since it needs to work on that version also.

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Feb 24, 2016 @ 10:05
    Simon Dingley
    0

    OK, I will have a think about how we can get around this in a backwards compatible way :)

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Mar 12, 2016 @ 07:50
    Richard Soeteman
    0

    Was thinking about the recordimporting events but will have a look if I can add a cancel option to those other events as well. But a workaround for your problem might be to throw an exception in importing event maybe?

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Mar 14, 2016 @ 13:48
    Simon Dingley
    0

    Thanks Richard - I think that having the ability to cancel in the BulkImporting or BulkImporting events would be useful if that is an option in a future version.

    Cheers, Simon

  • marcelh 171 posts 471 karma points
    Mar 15, 2017 @ 20:43
    marcelh
    0

    Hmm, just ran into the same issue here on a load-balanced, replicated environment. It appears that, when manually executed, the CMS Import process is being restarted after a random number of items is imported. Have you thought out anything in the meantime Richard? Or has anyone found a solid workaround?

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Mar 16, 2017 @ 07:02
    Richard Soeteman
    0

    Not yet, but the events simon describes should work. Or you need to make sure CMSImport can only be called from a single server.

    Best,

    Richard

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Mar 16, 2017 @ 09:19
    Simon Dingley
    0

    Here is what I implemented in my class that inherits from ApplicationEventHandler:

    void CmsImport_RecordImporting(object sender, CMSImport.Extensions.Providers.ImportProviders.EventArgs.RecordImportingEventArgs e)
    {
        // Get the current server role using the new features added in 7.2.4
        var serverRole = UmbracoContext.Current.Application.Services.ServerRegistrationService.GetCurrentServerRole();
    
        if (serverRole != ServerRole.Single && serverRole != ServerRole.Master)
        {
            e.Cancel = true;
            global::Umbraco.Core.Logging.LogHelper.Info<EventHandlers>("CMS Import Record Import Cancelled As Calling Server is not Master");
        }
    }
    
  • marcelh 171 posts 471 karma points
    Mar 16, 2017 @ 11:55
    marcelh
    0

    Excellent, I will implement that.

    How is determined that the CurrentServerRole is ServerRole.Master? Is there a switch I need to set somewhere? Our hosting company setup the load balanced environment, so I want to verify it's setup correctly.

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Mar 16, 2017 @ 12:05
    Simon Dingley
    0

    There is a table in the database where all servers are registered umbracoServer. Servers in your load balanced setup will be registered in this table when they are discovered by Umbraco.

    You can manually set the master server if you wish - see Explicit Master Scheduling server

    There is loads of really useful information on the Flexible Load Balancing setup.

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Mar 17, 2017 @ 06:51
    Richard Soeteman
    0

    Try the example above from Simon. That would work..

Please Sign in or register to post replies

Write your reply to:

Draft