Thursday 6 November 2014

Mendix and Java heap: The start

Building apps with the Mendix platform is very easy. You create the domain models, microflows and pages and press start. Mendix will start everything what is needed to run your application. Mendix makes sure that all your data is stored in the database and it's available in your microflows. As a business engineer it's a great a simple platform.

For the technical engineer I want to go a step further, because something makes Mendix run on the operating system. We all know that Mendix uses Java, an easy piece of middleware between Mendix and the OS. Java will handle the usage of memory and CPU on the OS. In my experience with Mendix the 'Out of Memory' exception is the most difficult one: an application that crashes on memory resources and isn't available any more. To understand how and why an OoM (Out of Memory exception) is triggered, we must first look how the Java memory works.

The Java memory is divided in separate parts: young generation, old generation (the Java heap) and the permanent generation. The permanent generation is the memory place to load in all classes and libraries. Default it has a size 64Mb, but at Mendix it's on 128Mb, what is enough. The young and the old generation is the place what we're going to discuss. All objects that are in memory (non-persistent entities, microflow objects, page objects, etc.) are stored there. The ratio between the young and old generation is 1:3, so the old generation is 3 times bigger than the young generation. The young generation small but fast and the old is large but slow.


When a microflow is started and is creating objects, the objects are pushed to the young generation. The generation keeps growing in size until it's reaching his max. At that point a minor garbage collection (short: minor GC) is triggered, removing all objects that aren't used anymore, making room for new objects. The minor GC doesn't take any resources, so you don't notice it's running. The objects that are still used, are of course saved. Those objects cannot be all the time in the young generation!


When an object survives 2 minor garbage collections it will be transfer to the old generation. The old generation is bigger and holds more objects/data. It haves more impact when that generation needs to be cleaned: a major garbage collection (short: major GC). 

At the graph above you see a Mendix app that is running about memory usage. The purple part is the young generation and the red is the old generation. Give a good look at the purple part, you see a saw structure, up and down. The red part is the old generation with 1 saw spike. Each time when the spike goes down a garbage collection is triggered. The minor GC happens a lot more than the major GC.

Mendix uses Java with that memory setup. All objects that are created and used are stored, starting, in the young generation and after in the old generation. Each generation uses garbage collection to make room for new objects. This means that the garbage collection runs in iterations: fill up, GC, fill up, GC, etc.
In the next blogpost I will discuss how and why Out of Memory exception are triggered, viewing all kind of Java memory graphs. How to read those graphs and placing them in context with other graphs.

Tuesday 21 October 2014

Rollback and associated objects

In a early post we've been talking about autocommitted objects in Mendix. Objects that have been automatically committed because of an association. But what do you do when then objects aren't used anymore? Actually delete or rollback the objects. 
 In the Domain Model you can set the delete behavior on associations. In the most cases the behavior is set to delete the associated objects as well. For each object Mendix will delete all objects that are associated. So with deleting one object you can delete a complete hierarchy of associated objects.

The delete behavior isn't only used for deleting objects, but also in a certain way for a rollback of an object. The setting is only used with a rollback of an instantiated object: a newly created object that haven't been committed yet. 

I've created a simple example project based on order management. The domain model is very simple with an 'Order', 'Orderline' and 'Products'. In testing the scenario the default Mendix functionality will be used, no custom created microflows. So the scenario: 
  • An 'Order' is instantiated.
  • Some 'Orderlines' are added and committed (the 'Order' will be autocommitted)
  • The 'Order' will be cancelled: executing a rollback.
No association delete behavior With association delete behavior
The 'Order' has properly been cleared, nothing in my database, but the created 'Orderlines' are still be present.
The 'Orderlines' are perfectly deleted and I have never explicit deleted. Based on the association delete behavior Mendix will delete them on a rollback.

Summarizing: Mendix works with objects that are connected with associations. Mendix doesn't know the logic hierarchy of objects that we know and program. If Mendix has to delete or rollback an object it only occurs on that instance, other objects aren't changed. The delete behavior on associations is really important to have a clean database.

Sunday 6 April 2014

Mendixworld!

3 and 4 April Mendixworld is happening in the Cruise Terminal in Rotterdam. An event with 18 sponsors and over 1500 registrations. Over 50 speakers will come, 37 track sessions from customers, the Research and Development team, Expert Services and more. There is a lot to do for everyone. I will give you a short update of what is happened, but most of all, what will be released?


First start: Derek Roos CEO of Mendix. His quote for his keynote: every company is becoming a software company. Technology can disrupt a market and for you as company you need to be innovative and differential. Implementing new ideas and products for your customers. 

But more important for you: the new release. A big milestone in the Mendix products for developers, partners and end-users: "Appcloud"! Build, deploy and share apps.  Everyone has ideas for new apps, workflows or business automation, but getting it to work and share it with your collegaes. Now it is possible with The Appcloud. How? It has three main features: launchpad, sandboxes and marketplace. 

Launchpad

One entry point for all your apps and open them with single sign-on service. Have an overview and bookmarks with the apps that you have within your company and your own creations. Just open and your logged in. But it goes further, start workflows, share documents and collaborate with your collegaes. Above all start your own project with the next feature: sandbox. 

Sandboxes

Each project will have his own sandbox cloud node. Create a project of your idea and deploy it in the Mendix cloud. Your application is direct available from your launchpad and share and build it with your collegaes. So you can test your app direct in a cloud environment. Because it is in your launchpad it will have single sign-on for all the users. So can you have a free cloud node, yes, with limitations. The app is limited to 10 users and won't be active all the time. After 1 hour inactivity the cloud node will go to sleep, but it will go live in 40 seconds after you access the URL. All your data will be saved and accessible for your users. But sometimes you don't have an idea to implement and there is a great feature for you!

Marketplace

A new upgraded App store that will have more content and completely workable project that can de downloaded. You can open a project within the App Store and deploy it in a sandbox with just three mouse clicks. The project will be downloaded and deployed in a teamserver so you can invite people to build the app and start implementing ideas. Beside downloading a project you van view the project in a running cloud environment. 

This is Appcloud a big step in bringing ideas to apps. All features will go live next April the 10th. So this is the first day of Mendix world. 

Friday 21 March 2014

Build custom validation messages

It has been a while I've added a new post. I've been moving to a new house. Some weeks later I've been come a father of a beautiful boy. So I hope you will forgive me for the late post.  That being said, let's get back to Mendix and build great apps. Off course I will build mine examples in Mendix 5.

The consistency of your data is of great importance of your business processes. If a part of data isn't correct, it can come corrupt with all consequences. On the other hand you want to use conditional visibility in your pages. The user must only see the fields what he needs to fill in. 
With Mendix you can add default validation checks on fields. Those only work when you don't use conditional visibility. When you set the property 'required' on a field that is placed on a row that is conditional visible, Mendix will generate the error: "Widget may not be required if the containing table row is conditionally visible." To implement validation checks on pages that contain conditional visibility it must be done with microflows.

In this example I use a page to edit a product: Product_NewEdit. The product can be of two types: Stockitem and Service. Based on that selection the user needs to fill in other types of data. The save of the product is handled by a microflow. The best practice to implement validation is the usage of a sub-microflow (a microflow that is called by a microflow). 

I create one microflow to validate a product: "SF_Product_Validation" and let the micrflow return a boolean: valid or not. The best way to start is to make a boolean variable that will used as the return value of the microflow. The boolean start with the value "true", we assume that the user gives the right information. Along the way of the microflow each attribute is checked and according how the conditional visibility is build in the page, the visible attributes are checked.
But why the use of a sub-microflow? To create an easier way for maintenance and possibility for unit testing. The best way to build microflows is by creating them in single functions, just like programming for example in Java. Microflows become testable for example unit testing.












Saturday 19 October 2013

Autocommit in microflows

At my first post I discussed a custom constrained by, by using a Microflow as a datasource. In the example I used an Order management and created a new "Orderline". I want to go on this example and discuss how Mendix works with a phenomenon "Autocommit". 

I'm going to save the new "OrderLine" with a Microflow trigger on the Form "OrderLine_NewEdit". Because it is a Microflow, it will not trigger the standard textbox validations. I have to build the validation myself. When the "OrderLine" is valid, I retrieve the "Order" from the association and calculate the total order price. Then the "OrderLine" is committed and the Form is closed.
When I debug the Microflow and look at the state of each object before and after committing the "OrderLine", something occurs. In the first step the "Order" as the "OrderLine" has the state "instantiated". The second step the "OrderLine" is committed to the database and gets the state "normal". The "Order" however has the state "autocommitted".


When the "OrderLine" is committed to the database, the association to the "Order" is also committed. In the database it isn't possible to refer to an object that doesn't exist. So Mendix inserts the "Order" and gives it the state "autocommitted". Based on this Mendix knows that cancelling the object must lead to a delete in the database, because it was't committed explicit by any logic.
  • Instantiated: A new object that is only present in the application memory.
  • Normal: An object that is present in the database.
  • Autocommitted: An object inserted in the database by an association.

Saturday 12 October 2013

Reference selector with special constrainted by

My first post:
We all have sometimes the situation that we have to commit an object, because the retrieval of data for an reference selector will not work. The data depends on the selection of something else but the selection isn't of the same object. For example we have a form for an "Orderline" what contains the reference selector for the "Product". Here comes the tricky part, it may only be that "Product" that belongs to a "Category" selected in the "Order". The domain model can looks likes this.
In the modeler you can select the "Constraint by" property on a reference selector to let Mendix automatic constraint the data based on the associations. But in this case the "Order" is a new object and not committed to the database, so the results for the "Product" reference selector is empty. 



The reason for the missing data has to do how the constraint by function works. The constraint by function works for the first association, in this case "ODM.OrderLine_Order", and the other associations needs to be in the database, except the last one. The association "ODM.Order_Category" was not in the database and therefor the results were empty.

To solve this issue isn't to be committing the "Order" object before adding a new "OrderLine", but to use a datasource Microflow for the Reference Selector. In that Microflow you can retrieve the "Order" over association (from the memory of Mendix). Than retrieve all products that are attached to category based on the association of "ODM.Order_Category". You just don't have to retrieve the "Category" object first.