Stephen Smith's Blog

All things Sage 300…

Multi-Threading in Sage 300

with 6 comments


In the early days of computing you could only run one program at a time on a PC. This meant if you wanted to run 10 programs at once you needed 10 computers. Then bit by bit multitasking made its way from mainframes and Unix to PCs, which allowed you to run quite a few programs at a time. Doing this meant you could run all 10 programs on one computer and this worked quite well. However it was still quite a high overhead since each program used a lot of memory and switching between them wasn’t all that fast. This lead to the idea of multi-threading where you ran very light weight tasks inside a single program. These used the same memory and resources as the program they were running in, so switching between them was very quick and the resources used adding more threads was very minimal.

Enter the Web

Think about how this affects you if you are building a web server. You want to basically run your programs on the web server and consider if you are running in the cloud. If you were single process then each web user running your app would have a separate VM to handle his requests and he would interact with that VM. There would be a load balancer that routes the users requests to the appropriate VM. This is quite an expensive way to run since you typically pay quite a bit a month for each VM. You might be surprised to learn that there are quite a few web applications that run this way. The reason they do this is for greater security since in this model each user is completely separated from each other since they are really running against separate machines.

The next level is to have the web server start a separate process to handle the requests for a given user. Basically when a new user signs on, a new process is started and all his requests are routed to this process. This model is typically used by applications that don’t want to support multi-threading or have other concerns. Again quite a few web applications run this way, but due to the high resource overhead of each process, you can only run at best a hundred or so users per server. Much better than one per VM, but still for the number of customers companies want to use their web site, this is quite expensive.

The next level of efficiency is to have each new user that signs on, just start a new thread. This is then way less overhead since you use only a small amount of thread local storage and switching between running threads is very quick. Now we are getting into have thousands of active users running off each web server.


This isn’t the whole story. The next step is to make your application stateless. This means that rather than each user getting their own thread, we put all the threads in a common pool. Then when a request for a user comes in, we just use a free thread from the pool to process the request. This way we don’t keep any state on the server for each user, and we only need the number of threads to be able to handle the number of active requests at a given time. This means while a user is thinking or reading a response, they are using no server resources. This is how you get a web applications like Facebook that can handle billions of users (of course they still use tens of thousands of servers to do this).

These techniques aren’t only done in the operating system software, but modern hardware architectures have been optimized for these techniques as well. Modern server CPUs have multiple cores which are very efficient at running multiple threads in parallel. To really take advantage of the power of these processors you really need to be a multi-threaded application.

Sage 300 ERP

As Sage 300 moves to the cloud, we have the same concerns. We’ve been properly multi-process since our 32-Bit version, back in the version 4 days (the 16-Bit version wasn’t really multi-process because 16-Bit Windows wasn’t properly multi-process).

We laid the foundations for multi-threaded operation in version 5.6A and then fully used it starting with version 6.0A for the Portal and Quote to Orders. Since then we’ve been improving our multi-threading as it is a very foundational component to being able to utilize our Business Logic Views from Web Applications.

If you look at a general text book on multi-threading it looks quite difficult since you are having to be very careful to protect the right memory at the right time. However a lot of times these books are looking at highly efficient parallel algorithms. Whereas we want a thread to handle a specific request for a specific user to completion. We never use multiple threads to handle a single request.

From an API point of view this means each thread has its own .Net session object and its own set of open Sage 300 Business Logic Views. We keep these cached in a pool to be checked out, but we never have more than one thread operating on one of these at a time. This then greatly simplifies how our multi-threading support needs to work.

If you’ve ever programmed our Business Logic Views, they have had the idea of being multi-threaded built into them from day 1. For instance all variables that need to be kept from call to call are stored associated with the view handle. There are no global variables in these Views. Further since even single threaded programs open multiple copies of the Views and use the recursively, a lot of this support has been fully tested since it’s required for these cases as well.

For version 5.6A we had to ensure that our API had thread safe alternatives for every API and that any API that wasn’t thread safe was deprecated. The sort of thing that causes threading problems is if an API function say just returns TRUE or FALSE on whether it succeeds and then if you want to know the real reason you need to check a global variable for the last error return code. The regular C runtime has a number of functions of this nature and we used to do this for our BCD processing. Alternatives to these functions were added to just return the error code. The reason the global variable is bad, is that another thread could call one of these functions and reset this variable in between you getting the failed response and then checking the variable.


If you’ve worked with our Views you will know that they are quite state-full. We can operate statelessly for simple operations like basic CRUD operations on simple objects. However for complicated data entry (like Order Entry or Invoice Entry) we do need to keep state while the user interacts with the document. This means we aren’t 100% stateless at this point, but our hope is that as we move forwards we can work to reduce the amount of state we keep, or reduce the number of interactions that require keeping state.

Testing Challenges

Fortunately testing tools are getting better and better. We can test using the Visual Studio Load Tester as well as using JMeter. Using these tools we can uncover various resource leaks, memory problems and deadlocks which occur when multiple threads go wrong. Static code analysis tools and good old fashioned code reviews are very useful in this regard as well.


As we progress the technology behind Sage 300, we need to make sure it has the foundations to run as a modern web application and our multi-threading support is key to this endeavor.


Written by smist08

February 22, 2014 at 5:37 pm

6 Responses

Subscribe to comments with RSS.

  1. […] Introduction In the early days of computing you could only run one program at a time on a PC. This meant if you wanted to run 10 programs at once you needed 10 computers. Then bit by bit multitaski…  […]

    • Steve, thanks for filling gaps in my understanding of business apps and multi-threading.

      I can’t see how the current .NET stack allows for Facebook type scale. I chatted these doubts with an core dev team member on a cross-country flight. Who acknowledged the 360 tool set was not currently being developed to backfit into MSDN.

      Can all the changes for removing state for complicated data entry (like Order Entry or Invoice Entry) be accomplished in application design or do new technologies, perhaps Node.js, need to appear for complex business apps to both scale somewhat like Facebook and have an on-premise distribution?

      (Also not trying to get you to spill any Sage beans)

      clive boulton

      February 23, 2014 at 7:05 pm

      • How to fully remove state will require some major changes in how we do complicated document entry screens like order entry. I suspect they will have to rely more on HTML storage and local JavaScript processing. Like you’ve mentioned before, perhaps languages like Dart can make this much easier. Right now to get to the web quicker we are using the current models which require state, but once we need to drive the hosting costs per user down, we are going to need to move this functionality to the client, or drastically reduce the interactivity of these screens.


        February 23, 2014 at 7:47 pm

  2. Hi Steve, thanks for the great article, but I’m wondering if you can clarify something for me….I keep hearing comments about “We are moving Sage 300 ERP to the cloud” and “Sage 300 ERP – Cloud 2.0″….but I haven’t really gotten the gist of what this actually is?

    I’m of course familiar with the “old” Sage 300 5.x and 6.0/6.1 programs that (other than the Portal and some of the web-based OE functions) is a traditional non-web-based app using VB-based UI’s calling the existing business objects. And that, as well, this program could be purchaseed by the end-user to run on-premise or they could sign up for the hosted version, which was basically them accessing Accpac thru remote desktop connection to your farm of Terminal (or Citrix) servers located (I think) in Vancouver or Atlanta.

    So how is “Sage 300 ERP Cloud 2.0” different? Is this an actual new, truly web-based version of “Accpac” that gets rid of the VB / locally installed components and becomes a true web app similar to the way CRM is a true web app? And of so, will this web app be available both thru the clous and for local installation on the end-user’s own in-hous IIS server? Or is it to be some kind of eviolving combination of the two technologies?

    Not trying to get you to spill any beans that you aren’t ready to yet officially announce, but I am trying to get some clarification of upcoming products that are already being discussed and promised by sage. Thanks!


    February 22, 2014 at 11:16 pm

    • These are all very interesting questions that I wish I could answer. But I can’t really comment on how the various technology pieces are going to be productized, for that you will have to wait for an official announcement, at which point I will have lots of blog articles on this topic. For the time being I’m a bit limited on what I can talk about.


      February 23, 2014 at 7:44 pm

  3. Inflection point coming for new languages…

    I can’t see users settling with less interactivity (reports Samsung has 48 core in the lab). Also reports multicore processors causing problems in Redmond with hosting Office servers at scale (and they aren’t doing complicated data entry). Resulting in some C# services being back ported to C++.

    More on multicore fragmentation with Bing GC

    Meanwhile Mountain View takes another multi-core direction. New languages. C++ services like ported to Go designed for multi-core slices.

    Dart designed for multi-core compiles javascript up to 25% faster. Great! But what I think matters is Dart GC cleans up third-party libraries like

    EOL now at 148,000 mostly Benelux customers, is far from Facebook usage, but poised for UK+US growth. I wouldn’t like to pay the hosting bill at 300,000 concurrents.

    clive boulton

    February 24, 2014 at 3:31 am

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: