Huge amount of Staging logs when sorting large Custom Tables

Fabio Xodo asked on March 22, 2018 10:03

Hi all,

I'm not an expert Kentico user (only Basic certification) but I have some experience in basic web parts and handler developing, too.

I have a general question I cannot find a simple answer to. I'm using K9.

The issue, in general, is that the management of sorting of element in huge custom tables (let's say 500 elements). The issue is related to the fact that it's needed to move every single element position by position, using the arrows. This 1. takes ages to move ever added element to it's position (500 clicks, if you have to move it to the first place) 2. generates an incredible amount of Staging synch data. It takes ages to synch.

Real life example: a table with 172 rows. Moving the last item only 19 position above (19 clicks) generated 62 pages of Staging log. Moving an item 1 position, 7 pages of log (25 item for each page). This is really unmanagable.

I see someone asked in te past about drag&drop sorting, but the request was refused. In case of Drag&Drop implemented, I'd expect 1 task for each drag&drop operation (update row + update following rows).

In the GeneralizedInfoWrapper class, though, there are only MoveObjectUp ad MoveObjectDown methods, no "MoveObjectTo(newIndex)" one. So I guess the entire underlying logic doesn't allow easy sorting in the way I want to do it.

Implementing a custom Drag & Drop layout would still be possible, but I don't want to log thousands of event into the Staging log, only for ordering. It takes ages to synch.

How could I solve this issue? The only solution I though could be

  • Attach to Staging Log Event and disabling Staging Log only for those large tables I want to manage in a different way

  • Create a custom layout for the custom table management, with or without drag & drop

  • add a button in the custom layout to fire the staging of the entire object at will (it means only one operation for each table row, this is absolutely acceptable)

Any hint about how to solve the problem in other ways?

Thanks, Fabio

Recent Answers


Zach Perry answered on March 22, 2018 17:53

My initial thought would be what logic are you using to manually determine the order? Can you do something else other than ItemOrder for sorting and then when you use the data add an order by some other column than ItemOrder.

If not, not sure if staging would be the best way to sync this data because it's going to have to create an update task for each item that was changed. If it is creating multiple tasks for each item, you might be able to reduce that to just a task for each item in its last order.

You might want to look into compare for Kentico, might speed syncing things up.

Lastly, you might be able to build something custom to sync the data, using something like Red Gate's SQL compare.

0 votesVote for this answer Mark as a Correct answer

Fabio Xodo answered on March 27, 2018 10:27

At the moment I'm using standard Custom Table ordering, nothing more. But the data in the tables has a strange orering... some items must be in the beginning, with a custom order field (some, it's sometimes hundreds) and the other is automatically ordered afterwards.

I can think of other scenarios where ordering manually huge a table is important, and the issue becomed annoying even with just 50 rows in the table.

If there was a drag&drop interface with 1 synch operation for drag&drop action, it would be totally fine, but as I wrot it seems Kentico doesn't support it.

Compare for Kentico and other DB aligning solutions are way to complex to manage something like this, that I consider should have been thought of when designing the feature.

Nevertheless, I'll try to create a custom layout and a module as I described above. It's a little shame, since it'll be overly time consumed. It seemed strange to me this kind of issue has never been considered, and I was hoping in a built-in solution.

0 votesVote for this answer Mark as a Correct answer

Fabio Xodo answered on April 4, 2018 11:42

So, in the end I couldn't solve this in an elegant way, but I implemented a temporary solution that may help someone else, in the future. So, I simply attached a Custom Handler to the ChangeOrder event, inside which I check for the tables I want to prevent staging synchronization during change order of elements, and simply turn off the logging for the request. It'll still log Create, Update, Delete events in table, so it'll not affect functioality too much.

Downsize is that, to appluy the sorting of elements to the next enviroment through Staging, once you finish to sort the elements you need to manually synch the entire Custom Table object. This takes just a couple of seconds, even for 500 rows, so it's not a huge issue for me.

Next step will be creating a custom layout for those tables, and adding a "Synch entire table" button at the top ;) Hope this'll help anyone trying to address the same issue.

using CMS.Base;
using CMS.CustomTables;
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.EventLog;
using CMS;

[assembly: RegisterModule(typeof(CustomHandlerModule))]
public class CustomHandlerModule : Module
{    
    public CustomHandlerModule() : base("CustomHandlerModule") { }

    protected override void OnInit()
    {   
        base.OnInit();
        EventLogProvider.LogInformation("Manage_ChangeOrder", "INFORMATION", "Custom Handler begin Init");                 
        ObjectEvents.ChangeOrder.Before += Manage_ChangeOrder;                    
    }

    private void Manage_ChangeOrder(object sender, ObjectChangeOrderEventArgs e)
        {           
            string tablename = e.Object.TypeInfo.ObjectType.ToLower();
            EventLogProvider.LogInformation("Manage_ChangeOrder", "INFORMATION", string.Format("Tablename {0}",tablename ));

            switch(tablename)
            {
                /*Use [namespace].[classname] from your custom table*/
                case "customtableitem.[namespace].[classname]": e.Using(new CMSActionContext(){LogSynchronization = false});break;
                /*other cases for other tables to manage, here*/
                default: break;
            }
        }
}
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.