Tale from inside TransactionScope

One of the last things you want to get from your Commerce site is that the order data is gone. What can be more confused than if your log shows that the cart has been converted into a purchase order, you even got the PO number, but after that, the order disappears? It’s nowhere to be found, even if you look into database. It’s kind of magic, but not the kind of magic you would want to have.

But everything happens for a reason. And actually it’s with a good reason: data consistency.

Episerver Commerce has the concept of TransactionScope. Simply put, it allows two or more database operations to be done as atomic: Either all of them succeed, or all of them will revert back. If a TransactionScope contains 3 operations A, B, C, then even if A, B succeeded, but C is yet to commit, and something goes wrong, then A and B would be reverted.

Continue reading “Tale from inside TransactionScope”

PS4 firmware 4.5 wifi problem fixed

And finally the much anticipated 4.5 firmware of PlayStation 4/4 Pro has arrived, with some very neat features: extended storage, custom themes. It’s a big improvement for PS4 users, well, almost: the firmware comes with a big problem for ones who are using wifi: the download speed is now terrible, and even worse, the lag in game is making the games unplayable. Before 4.5, I had no problem joining matches on Uncharted 4, and playing Titanfall was very smooth – ping is never more than 100ms. After 4.5, I can’t hardly join a match on Uncharted 4 (errors in connections), and the lag in Titanfall spikes to more than 2000ms, making the game totally unplayable. Test Internet Connection shows that I have a a few hundred Kbps upload and download, when the wifi connection is supposed to be 130Mbps (PS4 ony has 2.4Ghz wifi 802.11 b/g/n, only PS4 Pro has 5Ghz wifi), and my internet connection is 250/100Mbps, so that must be a big problem somewhere.

Continue reading “PS4 firmware 4.5 wifi problem fixed”

The Catalog UI trade-off: performance or better UI

I supposed this is a well known feature, but I was asked more than once about it, so it’s better to write something here to clarify the confusions.

If you have some very, very big catalogs, you probably have seen this “notification” in Catalog UI

By default, the Catalog UI groups a product and its variations in a parent-children view (they are not exactly parent-children, by the way). However, to do that, it needs to know about all the entries in that specific category. If it’s a small category, it should be no problem, but if it’s big one, then it’s inevitable slow. The lazy loading which the catalog content list only loads the contents when you scroll to them is not helping in this matter. Moreover, the grouping introduces an overhead for the UI, and having too many groups can severely affect the performance. Trust me, you won’t like a sluggish UI.

This improvement was introduced way back – 7.11 if I remember correctly – thanks to my colleague Magnus Rahl. To this day it’s still valuable – the performance was improved – but not that much to remove the threshold completely (And the improvement to the catalog versioning in Commerce 9 should have nothing to do with this).

When you see this notification, and if you’re unhappy with it, you have two (primary) options: Either to sub-categorize your category – i.e. introduce sub categories so each will have a smaller number of entries. Or increase the value of threshold.

Each approach has its own disadvantages. Sub-categorizing might break your SEO, while the second approach will undoubtedly effect the UI performance. Your call!

Now – the tricky part – which number to configure in SimplifiedCatalogListingThreshold setting. Obviously, it must be greater than the biggest number of entries in a category. But how to obtain that number? I’ve seen the confusion to raise that value to 3000, 5000, or even 10000 and it’s still not working. No, you can’t guess, you have to know for sure.

One simple option is to look at Commerce Manager Catalog Management. There is a small text in right corner of the list which shows the number of entries in that category (No, it’s not available in the Catalog UI, but I assume it would be helpful?)

 

The nuke option is to look at the database. Usually we recommend to avoid manipulate the database directly, as it can be dangerous – but here is a little code which only queries data (so practical harmless)

SELECT CatalogNodeId, Count(CatalogEntryId) 

FROM dbo.NodeEntryRelation

GROUP BY CatalogNodeId

ORDER BY Count(CatalogEntryId) DESC

Now you know the biggest number of the entries in a category – just change the threshold in setting. Try it and see if the UI Performance is acceptable to you.

Exploring Large Object Heap with WinDBG

This is the second part of http://vimvq1987.com/debug-net-memory-dump-windbg-crash-course-part-1/, – which is far from complete. In this post, we will explore the Large Object Heap (LOH) of a .NET application with WinDBG

Why LOH? It’s a special heap contains the memory objects which are more than 85000 bytes in size – which, previously, never compacted (that was changed with .NET 4.5 when you have an option to compact LOH, but beware of the consequences).

If you know about the generation garbage collection in CLR, you already know that when an object is no longer used, its memory will be claimed back for later use. GC do more than that, by trying to compact the “free” memory – so it’ll move (via copy and delete) the survived objects next to each other, therefore you’ll be a big, continuous free memory. This helps improving performance in upcoming allocations, but only until a point. If the objects are too big, then the costs of moving the objects around might outweigh the benefits. Microsoft did a bunch of performance test and they decided that 85000 bytes is the break point, where the costs are bigger than the performance gain. Then we have LOH, where the memory is almost never compacted.

Continue reading “Exploring Large Object Heap with WinDBG”

Find.Commerce is not for Commerce Manager

I’ve seen this more than once, and this can be quite tiresome to fix the problem(s) after that. So here the TL;DR: If you are installing Find.Commerce to Commerce Manager, you are doing it wrong.

You’ll probably end up in the error like this

While loading .NET types from "EPiServer.Find.UI" the following error(s) was reported:

     - System.IO.FileNotFoundException: Could not load file or assembly 'EPiServer.Cms.Shell.UI, Version=9.3.8.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7' or one of its dependencies. The system cannot find the file specified.
File name: 'EPiServer.Cms.Shell.UI, Version=9.3.8.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7'

=== Pre-bind state information ===
LOG: DisplayName = EPiServer.Cms.Shell.UI, Version=9.3.8.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7
 (Fully-specified)
LOG: Appbase = file:///C:/EPiServer/FindSearchProvider/backend/
LOG: Initial PrivatePath = C:\EPiServer\FindSearchProvider\backend\bin
Calling assembly : EPiServer.Find.UI, Version=12.0.0.4448, Culture=neutral, PublicKeyToken=8fe83dea738b45b7.

Continue reading “Find.Commerce is not for Commerce Manager”

Why I don’t code in my free time, and why you should not, too.

Just read a story that bogged my mind. A “Technical/team lead” told a story, as an interviewer, he asked “a very good” candidate,  what does he/she like, and what does he/she do on his/her spare time.

The answers were reading books, watching movies, and cooking.

The candidate did not get hired, even thought he/she excelled at other technical questions. The interviewer expected him/her to “work” on his/her spare time. Like a pet project – to learn something new, or to sharpen the skills. The interviewer hired another candidate who does exactly that.

I’m glad I was not neither in that kind of interview, nor I have that kind of boss.

Continue reading “Why I don’t code in my free time, and why you should not, too.”

1600 vs 1400 vs 1200 rpm washing machine

I got this question before – and now I bought one, I hope I can help you choosing the right washing machine.

You might have read other answers on the Internet – and yes most of them are saying a 1200 rpm washing machine is just as good as a 1600 rpm one, in term of the dryness of the clothes.

Wrong!

That might be true with synthetic clothes – which are the easiest ones to dry. But for cotton, it’s a big different. I tried same clothes with both 1400 rpm and 1600 rpm and my clothes are noticeable drier when it comes out of 1600 rpm mode. 1200 rpm, of course, is not even close.

My washing machine, a “high-end” model from Bosch has common presets:

  • 1600 rpm for cotton
  • 1200 rpm for synthetic
  • 1400 rpm for the mix of two above.

And for me, that totally makes senses. I noticed this kind of setting across many manufacturer – the cotton preset is always the one with fastest rotation available.

1600 rpm is best for cotton.

[quads id=2]

That means the time you need to dry it, as well as the consumption of the dryer, will be less.

And to endure 1600 rpm spinning speed, the washing machine must be sturdier and more balanced. In other words, it must be built better – so you can expect it to last longer, at least for the motor part. You can see that in same series, the higher model which supports 1600 rpm is always heavier than the lower end models. Yes – it’s to support and withstand the faster rotation.

An example is a 1400 rpm machine from Bosch, series 6 WAT2869MSN, only weighs 72 kg

https://www.bosch-home.se/produktlista/tvattmaskiner-och-torktumlare/tvattmaskiner/frontmatade-tvattmaskiner/WAT2869MSN 

A series 8, (which supports 1600rpm) WAWH26M9SN, weighs 81 kg

https://www.bosch-home.se/produktlista/tvattmaskiner-och-torktumlare/tvattmaskiner/frontmatade-tvattmaskiner/WAWH26M9SN

Given they have fairly same size, and fairly equivalent features, the difference in weight, of course, have to come from inside. The higher model has more weight to make sure it is stable with the rotation of 1600 rounds per minute.

So if you have cotton clothes – which I suppose you do – and if you can afford it, I would suggest to go to 1600 rpm one. It’s nice to have the option, it is nice to have drier (cotton) clothes, and it’s nice to have a washing machine that lasts longer.

Episerver Commerce performance optimization – part 2

Or lock or no lock – that’s the question.

This is the second part of the series on how can you improve the performance of Episerver Commerce site – or more precisely, to avoid the deadlocks and 100% CPU usage. This is not Commerce specific actually, and you can apply the knowledge and techniques here for a normal CMS site as well.

It’s a common and well-known best practice to store the slow-to-retrieve data in cache. These days memory is cheap – not free – but cheap. Yet it is still much faster than the fastest PCIe SSD in the market (if your site is running on traditional HDD, it’s not even close). And having objects in cache means you won’t have to open the connection to SQL Server, wait for it to read the data and send back to you – which all cost time. And if the object you need is a complex one, for example a Catalog content, you will also save the time needed to construct the object. Even if it’s fast, it is still not instantaneous, and it will cost you both memory and CPU cycles. All in all – caching is the right way to go. But how to get it right?

One common mistake for to have no lock when you load the data for the first time and insert it into cache.

Continue reading “Episerver Commerce performance optimization – part 2”

May I trust your site?

If your site has exceeding ads all over places, or you ask me to disable my ad-blocker, then no.

If your site ask me to subscribe to your newsletter after 5 seconds, even before I read your post’s title, then no.

If your site has auto-play videos that continue to play even if I scrolled down, then no.

If your site has no comment section, then no.

If you don’t moderate your comment section and it’s full of spam, then no.

If your site open pops up, then no.

If you site doesn’t have HTTPS, then that might raise suspects. (Yes you should look up in the address, this site is not HTTPS-enabled, and that’s entirely my fault, but I would never ask for your information more than a name and an email address (you don’t have to give a real one)). I know, I should have spent time to enable HTTPS on this site, I’m just too busy writing content (another way to say I’m lazy).  (I added HTTPS now, isn’t it nice?)

 

 

Find indexing job + HierarchicalCatalogPartialRouter: A note

I ran into this problem recently and while in the end it’s quite simple issue (Everything is simple if we understand it, right?), it costed me quite many hairs in the process – as it involved debugging with 3 solutions – Find.Commerce (where the problem appears), Commerce (where the router does the work), CMS Core (where the routers are handled). It was both fun, and confusing.

The problem as a customer has this code in an initialization module:

            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var referenceConverter = ServiceLocator.Current.GetInstance<ReferenceConverter>();

            var firstCatalog = contentLoader.GetChildren<CatalogContent>(referenceConverter.GetRootLink()).FirstOrDefault();

            var partialRouter = new HierarchicalCatalogPartialRouter(() => SiteDefinition.Current.StartPage, firstCatalog, false);

            routes.RegisterPartialRouter(partialRouter);

Continue reading “Find indexing job + HierarchicalCatalogPartialRouter: A note”