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.
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.
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.
[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
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.
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.
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?)
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);
This is a first part of a long series (which have no planned number of parts) as the lessons I learned during trouble shouting customers’ performance problems. I’m quite of addicted to the support cases reported by customers, especially the ones with performance problems. Every time I jump into such support case, I’ll be with less hairs, but I also learn some new things: Implementations are different from cases to cases, but there are some common mistakes which will hurt your website performance. This series will try to point out those mistakes so you get your performance gain, for (almost) free:
Mistake 1: Loading to much content
It’s easy to load contents, especially with the new content APIs. Given an universal ContentReference, you can load a content with a simple line of code. By default, the loaded content is cached, so you might think it’s cheap, or even free to load a content. Think again.
Even with the raising popularity of FindCommerce, I suspect that many Commerce customers are still using the search provider system, as it comes with an undeniable benefit: It can be used within Commerce Manager. And while I suspect a majority of you have the eventual indexing turned on (aka the entry will be indexed as soon as it’s changed), many still index the entries on demand. Aka manually, or periodically via scheduled job.
We received a report from a customer recently as the indexing timeout, as he was indexing a large amount of entries (about 250.000 entries on 8 catalogs). When we looked into the problem, we discover a possible improvement which is almost free for you.
Recently I worked on two support cases from our customers as they see SQL Server errors, such as “System.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint “FK_ShipmentEx_Shipment”. The conflict occurred in database “dbCommerce”, table “dbo.Shipment”, column ‘ShipmentId’“, or “System.Data.SqlClient.SqlException (0x80131904): The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.”
These errors happened randomly, during the high load times – it seems to be affected by the concurrency level.
What was wrong? and why?
It took me a good amount of time, and good amount of hairs, too. The actual error is another one, and the one above is just the “by product”.
The cart system in Episerver Commerce suffers from a design flaw: it shares (almost) everything with the purchase orders. ShoppingCart is just another metaclass extended OrderGroup, so it’ll use the same OrderGroup, OrderForm, Shipment, LineItem and OrderAddress tables in the database, like PurchaseOrder and PaymentPlan. At first, it seems to be reasonable approach. But when you have hundreds, or thousands of customers visiting your website (and you would be happy to see that ;)) – problems start to appear.
For a good long amount of time, workflows have been an essential part of Episerver Commerce (and even before that, Mediachase eCF). Once you get into order system, you just can’t escape workflows – because you need them. They handle many – if not all things, from validating items, checking inventories (to make sure that you are not selling something out-of-stock, or just discontinued (think of Galaxy Note 7, poor little shiny phone)), applying promotions, calculating taxes, process payments, and finally adjust inventories (yay, a customer places an order, let’s ship to him as soon as possible, firstly allocate the goods for him). And workflows are even required by later processing – when you complete the shipments (another happy customer!), or when you issue a return or an exchange (well, let’s keep the customer still happy).