SlideShare a Scribd company logo
PUSHING UMBRACO
TO THE LIMITS
While building New Heroes
• Lead developer @coloursinternet
• Umbraco MVP 2016/2017
• Working with Umbraco since late 2007 (v3)
Dave Woestenborghs
@dawoe21
• Senior Developer @coloursinternet
• 3 times Umbraco MVP
• Working with Umbraco since 2009 (v4)
• Was looking for a job last year during CG. Since
than only been working on this project.
Jeroen Breuer
@j_breuer
INTRODUCTION
Pushing umbraco to the limits
THE AGENDA
1. What is New Heroes
2. Statistics
3. Load balance setup
4. 1-1 multilingual
5. Database access
6. Miniprofiler
7. Performance tweaking
8. Pluginmanager
9. Other techniques
10. Questions
NEW HEROES
New Heroes is an online platform that allows access to soft skills and
leadership training for anyone , anytime and anywhere in the world . Through
the platform , users can continue develop in the areas of communication,
personal empowerment and leadership.
5
NEW HEROES
For a fixed and low monthly
amount, both individuals and
businesses, have unlimited usage
of all trainings , also known as
'learning journeys ' .
VIDEO
PUSHINGUMBRACOTOTHELIMITS
The statistics
• Lines of code : 69k
• Git commits : 7500+
• Community property editors : 4
• Community tools : 7
• Custom build property editors : 1
STATS CODE
PUSHINGUMBRACOTOTHELIMITS
The statistics
• Umbraco Version : 7.3.8 (started on 7.3.0-beta1)
• Number of media items : 1263
• Number of content items : 8411
• Number of cache instructions : +37k
• Number of doctypes : 205
STATS UMBRACO
PUSHINGUMBRACOTOTHELIMITS
The statistics
• Number of times that Jeroen deleted the wrong doctype : 2
STATS MISTAKES
Development goals
• Application should autoscale
• Use core/community functionality where possible
• Focus on performance
• DRY backend and front end
• 1-1 multilingual for reusable content
OUR GOALS
PUSHINGUMBRACOTOTHELIMITS
PUSHINGUMBRACOTOTHELIMITS
Load balance setup
• Hosted on Azure (Blob storage / redis cache)
• VM with editors environment (master)
• Front end runs on auto scaling web app (slaves)
• Started on 7.3 beta because of the flexible loadbalancing (no
config for loadbalancing needed)
• But you need to have some config tweaks. So make sure you
read the loadbalancing docs on our.umbraco.org
LOADBALANCED
12
LOADBALANCED
• Use correct events to update custom cache (e.g. output cache)
• Published event is only executed on the server where it’s triggered.
Not on all other servers.
• Hook in to CacheRefreshers CacheUpdated event instead.
PageCacheRefresher.CacheUpdated += (sender, args) =>
{
{
// clear cache here
};
13
LOADBALANCED
• For custom needs it’s possible to create your own cache refreshers .
• Need to create a class that implements ICacheRefresher interface.
• Umbraco has some base classes that you can inherit from like
CacheRefresherBase and JsonCacheRefresherBase
• When your data is changed tell the distributed cache that it needs to
execute a method on the cacherefresher :
• DistributedCache.Instance.RefreshAll(CustomCacheRefresherGuid);
• And handle the CacheUpdated event for the cache refresher
14
1-1 multilingual
MULTILINGUAL
SETUP
15
MULTILINGUALSETUP
• Still uses a separate language tree
• Nodes that need to be reused in a shared data folder.
• Uses a UrlProvider and ContentFinder.
• Vorto for the 1-1 properties
• Nested Content to create fieldsets
• ModelsBuilder for strongly typed fieldsets.
• http://24days.in/umbraco/2015/multilingual-vorto-nested-content/
16
PUSHINGUMBRACOTOTHELIMITS
17
PUSHINGUMBRACOTOTHELIMITS
18
PUSHINGUMBRACOTOTHELIMITS
19
PUSHINGUMBRACOTOTHELIMITS
20
PUSHINGUMBRACOTOTHELIMITS
21
PUSHINGUMBRACOTOTHELIMITS
22
RENDER
23
MODELSBUILDER
24
URLPROVIDER
25
CONTENTFINDER
Database access
• Needed custom database tables for storing user data
• Needed to select a ORM
• Decided to go with PetaPoco because it ships with Umbraco.
DATABASE ACCESS
PUSHINGUMBRACOTOTHELIMITS
27
EXAMPLEPOCO
28
CRUDOPERATIONS
29
Database access
• Goal was to do database maintenance (creating, modifying
tables) from code so that it becomes part of the automated build
process.
• We’re using uSync for all Umbraco parts.
MAINTENANCE
PUSHINGUMBRACOTOTHELIMITS
30
PETAPOCOATTEMPT
31
• Only possible to create and drop tables
• No ways to alter tables, add constraints and indexes
• Needed an alternative
PETA POCO ATTEMPT
PUSHINGUMBRACOTOTHELIMITS
Database access
32
• Migrations is used by Umbraco process
• Have been in place since 6.0.0
• Open to the general public since 7.3.0
MIGRATIONS
PUSHINGUMBRACOTOTHELIMITS
Database access
33
MIGRATIONS
34
MIGRATIONS
35
MIGRATIONS
36
MIGRATIONS
37
Miniprofiler
PERFORMANCE
MINIPROFILER
38
LOGGINGEXECUTIONTIME
39
LOGGINGEXECUTIONTIME
40
LOGGINGEXECUTIONTIME
41
MVCWITHHTML.ACTION
42
MVCWITHHTML.ACTION
43
EXAMINE
44
DATABASE
Pluginmanager
Whenever types need to be found in assemblies in order to add
them to resolvers, the PluginManager should be used. The
TypeFinder should never be used directly in any code except for in
PluginManager extension methods or in the PluingManager itself.
• PluginManager.Current.ResolveTypes<T>
• PluginManager.Current.ResolveAttributedTypes<T>()
• PluginManager.Current.ResolveTypesWithAttribute<T,S>
PLUGINMANAGER
PUSHINGUMBRACOTOTHELIMITS
Pluginmanager
A Resolver is an class that returns a plugin object or multiple
plugin objects. There are 2 types of Resolvers: A single object
resolver and a multiple object resolver.
Some examples :
Single object resolver :
DefaultRenderMvcControllerResolver.Current
Multiple object resolver : UrlProviderResolver.Current
OBJECTRESOLVERS
PUSHINGUMBRACOTOTHELIMITS
47
EXAMPLE
48
EXAMPLE
49
EXAMPLE
50
Pluginmanager
EXAMPLE
• Only possible to create and drop tables
• No ways to alter tables, add constraints and indexes
• Needed an alternative
PUSHINGUMBRACOTOTHELIMITS
51
Other techniques
OTHER TECHNIQUES
• Custom section with Angular + Umbraco WebApi + PetaPoco
• Virtual nodes
• Service API (ContentService, MediaService, RelationService)
• ImageProcessor to resize images
• Dependency Injection
• Custom property value converters
PUSHINGUMBRACOTOTHELIMITS
Pushing umbraco to the limits
QUESTIONS?

More Related Content

PPTX
Azure Umbraco workshop
PPTX
Azure and Umbraco CMS
PPTX
Web Assembly Big Picture
PDF
Introduction of webpack 4
PPTX
Cross platform dotnet development using dotnet core
PPTX
Interoperable OpenStack guest provisioning with Cloudbase-Init
PPTX
Into to Webassmbly
PPTX
Don't worry with bower
Azure Umbraco workshop
Azure and Umbraco CMS
Web Assembly Big Picture
Introduction of webpack 4
Cross platform dotnet development using dotnet core
Interoperable OpenStack guest provisioning with Cloudbase-Init
Into to Webassmbly
Don't worry with bower

What's hot (20)

PPTX
Drupal 8, Symfony and Content Management
PDF
WordPress development checklist
PDF
AWS, is it interesting?
PPTX
DevDay 2018 - Blazor
PPTX
MEAN stack
PDF
Start with Bolt and Go Ez - eZ Publish Summer Camp 2015
PPTX
Introduction to JS frameworks
PDF
Building Drupal 8 Sites
PPTX
JustSharing: Lessons in Xamarin development
PDF
Mini-Training: NancyFX
PDF
Polkadot encode club moonbeam
PPTX
Introduction to ASP.NET Core
PDF
WebAssembly with Rust
PDF
Build your first DApp using Substrate Framework - Part I
PPTX
WordPress Multilingual: WordCamp Antwerp 2016
PPT
Linux for Web Developers
PDF
Building Desktop RIAs with PHP, HTML & Javascript in AIR
PPTX
Instruction to build Apache CloudStack docs with Sphinx
PPTX
introduction to js
PPT
Get MEAN! Node.js and the MEAN stack
Drupal 8, Symfony and Content Management
WordPress development checklist
AWS, is it interesting?
DevDay 2018 - Blazor
MEAN stack
Start with Bolt and Go Ez - eZ Publish Summer Camp 2015
Introduction to JS frameworks
Building Drupal 8 Sites
JustSharing: Lessons in Xamarin development
Mini-Training: NancyFX
Polkadot encode club moonbeam
Introduction to ASP.NET Core
WebAssembly with Rust
Build your first DApp using Substrate Framework - Part I
WordPress Multilingual: WordCamp Antwerp 2016
Linux for Web Developers
Building Desktop RIAs with PHP, HTML & Javascript in AIR
Instruction to build Apache CloudStack docs with Sphinx
introduction to js
Get MEAN! Node.js and the MEAN stack
Ad

Viewers also liked (6)

PDF
Selling Umbraco - CodeGarden 2015
PDF
Selling umbraco
PDF
Umbraco 5th Birthday from SAS Design
PPTX
Umbraco - .NET-owy scyzoryk w świecie CMS-ów
PDF
McrUmbMeetup 22 May 14: Umbraco and Amazon
PPTX
Introduction To Umbraco
Selling Umbraco - CodeGarden 2015
Selling umbraco
Umbraco 5th Birthday from SAS Design
Umbraco - .NET-owy scyzoryk w świecie CMS-ów
McrUmbMeetup 22 May 14: Umbraco and Amazon
Introduction To Umbraco
Ad

Similar to Pushing umbraco to the limits (20)

PPTX
J&Js adventures with agency best practice & the hybrid MVC framework - Umbrac...
PPTX
7 Reasons Why Umbraco CMS is the Best for Small Business
PPTX
Umbraco in 10 minutes
PPTX
MVC Puree - Approaches to MVC with Umbraco
PDF
When Less is More
PPTX
Personalisation packages in Umbraco
PDF
Umbraco development across large and distributed teams
PDF
What is Umbraco.pdf
PPTX
Large scale, cloud computing and scalability with Umbraco
PDF
Becoming a superhero - Umbraco DK festival 2013 - notes
PPTX
Umbraco OktoberFest 2014
PPTX
An Introduction to Umbraco
PPTX
Fast and furious(ly) multilingual: Publishing of EU politics in 24 languages ...
PDF
Umbraco Migration.pdf
PDF
The need for speed uk fest
PPTX
IBM Connect 2017 - Beyond Domino Designer
PDF
Umbraco - DUUGFest 17 -The need for speed
PPTX
"Umbraco MVC - a journey of discovery" - Lotte Pitcher
PPTX
Introduction to Umbraco
PPTX
Dynamics CRM high volume systems - lessons from the field
J&Js adventures with agency best practice & the hybrid MVC framework - Umbrac...
7 Reasons Why Umbraco CMS is the Best for Small Business
Umbraco in 10 minutes
MVC Puree - Approaches to MVC with Umbraco
When Less is More
Personalisation packages in Umbraco
Umbraco development across large and distributed teams
What is Umbraco.pdf
Large scale, cloud computing and scalability with Umbraco
Becoming a superhero - Umbraco DK festival 2013 - notes
Umbraco OktoberFest 2014
An Introduction to Umbraco
Fast and furious(ly) multilingual: Publishing of EU politics in 24 languages ...
Umbraco Migration.pdf
The need for speed uk fest
IBM Connect 2017 - Beyond Domino Designer
Umbraco - DUUGFest 17 -The need for speed
"Umbraco MVC - a journey of discovery" - Lotte Pitcher
Introduction to Umbraco
Dynamics CRM high volume systems - lessons from the field

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
Cloud computing and distributed systems.
PDF
Empathic Computing: Creating Shared Understanding
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
cuic standard and advanced reporting.pdf
PDF
KodekX | Application Modernization Development
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Electronic commerce courselecture one. Pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
Teaching material agriculture food technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Spectral efficient network and resource selection model in 5G networks
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
MIND Revenue Release Quarter 2 2025 Press Release
Diabetes mellitus diagnosis method based random forest with bat algorithm
Encapsulation_ Review paper, used for researhc scholars
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Cloud computing and distributed systems.
Empathic Computing: Creating Shared Understanding
Unlocking AI with Model Context Protocol (MCP)
Per capita expenditure prediction using model stacking based on satellite ima...
The AUB Centre for AI in Media Proposal.docx
The Rise and Fall of 3GPP – Time for a Sabbatical?
cuic standard and advanced reporting.pdf
KodekX | Application Modernization Development
Review of recent advances in non-invasive hemoglobin estimation
Electronic commerce courselecture one. Pdf
Understanding_Digital_Forensics_Presentation.pptx

Pushing umbraco to the limits

Editor's Notes

  • #8: Community editors used are Nested Content, Vorto, nuPickers and RJP Multi Url picker Thank Hendy, Lee and Matt for their great packages. Other tools include uSync, Diplo trace log viewer, CMSImport, Bulkmanager, Load balancing dashboard, Zbu Models Builder, Core Value Convertors One custom build property editor for managing “short” urls => is a candidate to be open sourced
  • #9: Started on Umbraco 7.3 beta so we could use the new flexible loadbalancing We have already a big amount of content that keeps growing Cache instructions are stored in the database so the new load balancing knows what to updated on all the servers. More on that later
  • #10: First I deleted it on dev environment. After that I opened the qa environment to use that version to recreate it. Than I also deleted it on the qa environment. A lot of test content was lost because of that. Luckily we had uSync in place so it was easy to import the document type again.
  • #12: Flexible load balancing works on the database instead of configuration in umbracosettings.config When a Umbraco application starts up it registers itself in the table umbracoServer. When changes are made cache instructions are written to table umbracoCacheInstruction. Each server keeps track of executed cache instructions in App_Data/Temp/DistCache. If behind it will catch up. Check happens at start of request to application Created load balancing dashboard for easy info on registered servers Config tweaks needed for storing umbraco.config and examine indexes in temp storage of web app instance
  • #13: When you have your own caches like output cache and you are running in a loadbalanced environment it’s important you hook in to the correct event. Most people hook in to Published Event to do this, but published event is only executed on the server where it’s triggered. In our case the VM with editors environment. You will need to hook in to cache Updated event of the different cache refreshers like PageCacheRefresher, MediaCacheRefresher, DictionairyCacheRefresher These will get executed after the cacheInstructions (from DB) have been processed.
  • #14: In the new heroes project a lot of data in custom datatables is managed through the umbraco backend in a custom section. The data is not changed frequently so we can cache it for a long time and don’t want it cleared by publishing actions. You can create your own cache refresher. By inheriting one of the base classes in the core. When your data is changed you tell the distribute cache to execute a action on all servers. Additionally you can hook in to a cache updated event after cache has been updated
  • #16: The node name isn’t used for the URL. We have a Vorto textstring which can change the URL per language. The node name is a code which the content editor uses. Vorto converts a property editor into a multilingual property by allowing you to enter multiple values per language. Nested Content can create a single or repeatable fieldset based on a document type. ModelsBuilder is a tool to generate strongly-typed published content models. It’s in the core since Umbraco 7.4.
  • #17: This is the end result on New Heroes. I’ll know quickly explain how we’ve done this with a simple example.
  • #18: 1 Create a document type with these properties.
  • #19: 2 Create a Nested Content data type with this document type and set min and max to 1.
  • #20: 3. Create a Vorto data type which has the Nested Content document type.
  • #21: 4. Put this Vorto data type on the News Items document type.
  • #22: Are you still following me? 6. It looks the same as the New Heroes result. Again. You can all read this in the blog article too.
  • #23: Code from the 1-1 multilingual example The Nested Content fieldset will return an IPublishedContent. Because it’s in Vorto we can get a translated IPublishedContent which will have all the properties in the correct language. Render the IPublishedContent properties.
  • #24: We still get the translated IPublishedContent from Vorto. The ModelsBuilder generated a model for the document type which we used for the Nested Content. The IPublishedContent can be passed to this model to get the strongly-typed model. Rendering the properties is easier now.
  • #25: A simple UrlProvider example. Not used in New Heroes. A single node used for 1-1 multilingual can get different URLs per language like this. Extremely powerful! Used for all nodes that are 1-1 multilingual with Vorto.
  • #26: If the URL of a node is changed with a UrlProvider it will give a 404 if you visit that URL. The ContentFinder can match the URL to a content node and return that. rootNodes.DescendantsOrSelf is bad for performance. You should get the nodes you need first. Not important for this example.
  • #27: We need to store progress of learning journeys and learning element and other user related data Discussion was to use EF, but decided to use PetaPoco because this is used by Umbraco and keeps down external plugins
  • #28: Decorate your class with table name and primary key attribute Decorate your properties with attributes
  • #29: Crud methods are done using strongly typed objects..no SQL query needed, but you can do it if you need more control over the query Linq way of writing where clauses
  • #30: Because we have build server set up for CI we don’t want to update our db schema by running scripts on the database every time we deploy. The maintenance of the db should be handled by the application
  • #31: First attempt was by using the database schema helper to create tables base on our POCO
  • #32: This works fine if you only want to create or drop tables. But there is no way to alter tables, add constraints, indexes or other db objects like stored procedures or views. So a better alternative was needed
  • #33: Had a look at the Umbraco source on how they handle the upgrades..and discovered the migration framework It has been in Umbraco since version 6.0.0 Since 7.3.0 exuted migrations are stored in db with an application name. Benefit is that DB upgrade is run when db is behind on Umbraco version. Also can be used for other migrations than Umbraco because of the application name Migrations are the way to go if you application or package needs custom database tables
  • #34: First you need to create a class that inherits from MigrationBase. You will need to override 2 methods Up and Down You need to decorate the class with the Migration Attribute so it’s picked up by Umbraco In the attribute you specify the version number of the migration, the execution order of the file (version can have multiple files), and the application name that the migration is for. Additionally you can specify a minimum version that needs to be run before this can be run. E.g umbraco runs some migrations only if your current version is for example 7.3.0
  • #35: Some examples of the migrations syntax Creating a table Adding a column Executing a sql statement Many more options available like dropping a table, creating constraints and indexes, inserting/updating/deleting records. There is even a option to execute code, but never tried it
  • #36: We run database migrations on startup of the web app. The code checks for the latest migration version in the table “umbracoMigration” We set new target version and check if it needs to be executed
  • #37: Dave: After we have determined if we need to execute migrations we create a new migrationrunner And execute it against the database Jeroen: We’re probably one of the first that used the migrations for our own custom tables, because we did run into some issues. We had a migration called 7.3.4 and no matter what we did it was never executed. After doing a deep investigation we found out that the product name wasn’t checked and since Umbraco itself was already upgraded to 7.3.4 it thought it had already run. It was very coincidence to run into something like this and it can drive you pretty crazy ;-). Luckily Dave created a PR and now it’s fixed in 7.3.7 (http://issues.umbraco.org/issue/U4-7872).
  • #39: To find performance issues you can log the execution time of your methods to the log. There are 2 options that will log differently. This information is also visible in the miniprofiler
  • #40: With Miniprofiler you get a clear overview of how long a page takes.
  • #41: We even found out that after a Save and Publish Umbraco did a query for each dictionary item so we build are own cache layer around it.
  • #42: All index methods use the DonutOutputCache attribute for better performance. LongPageCache is default. Order so other attributes execute first. For example to check credentials. We don’t do a lot of logic in the index method. With TraceDuration we can see how long all logic in the index method takes place. These are also all the html actions on the view.
  • #43: In the view we do a lot of Html.Action. This way the code is better separated and easier to reuse. We can also exclude a part and let the child action have a donut cache with another time.
  • #44: We used this code a lot in the UrlHelper to get the nodes of a specific doctype and return those URLs. This was first done with Umbraco.TypedContentAtRoot().DescendantsOrSelf("alias") which was very slow. Could also be used in the ContentFinder to return all nodes of a document type. For example all nodes of the Newsitem document type.
  • #45: We’ve had some Examine corruption issues so instead you can also get the ids by querying the database.
  • #46: The pluginmanager is a usefull tool when you need to find certain classes in your application
  • #47: Object resolvers provide some kind of “Inversion of Control”. At start up you initialize the resolver with the needed types (from plugin manager). After the application has started you can the you use your resolver to get the types. Some more example in the core are ContentFinderResolver, PropertyValueConvertersResolver If you wish to create a package that is extendable to third parties the plugin manager and object resolver are your friends
  • #48: First step would to create a extension method on the plugin manager to find a certain type
  • #49: The next step is to create a resolver for your type. In this example we created a resolver that return multiple objects
  • #50: Then the final thing is to set up your resolver during the startup of umbraco in the ApplicationInitialized event
  • #51: Now you can use in your application and you can use the object resolver to find your types. So we created some kind of inversion of control without a IOC container framework like Autofac
  • #52: Now everyone is on 7.4, but I remember the 4.7 days. It would have been impossible to build this. Umbraco and the core functionalities are awesome! We’ve learned a lot from the 24 days blog posts.