I am planning to use Spring State Machine to control an execution workflow. The system is expected to receive requests from multiple users and each user may be assigned to multiple workflows. My initial idea was to have one instance of SM per workflow and every time an user perform a step in the workflow, I would use its identifier to restore the machine from a persistent storage, input the new event and store the updated SM.
I've read around that initialising a SM is an expensive operation and some people recommend having a single instance of it, but "rehydrate" that instance with some data. My understanding is that this would be more effective, but I think it would become a "blocking" operation, in other words, one workflow would need to wait for the previous one to be finished/released before-hand. Since I'm newbie on this topic, can anyone shed some light on the best alternatives for my use case and perhaps pieces of code to illustrate the differences? (PS: I'm using v2.4.0)
I was first implementing the "rehydrate" mechanism because as you said, it made sense and was also used in the "persist" example of spring-statemachine.
Howewer, running performance tests against my API showed that using a single instance fails when using the StateMachine as an #Autowired Bean with the prototype scope as it is described in that example. What happens is that simultaneous requests against my API override that Statemachine Bean and the first request fails as the statemachine changes when writing back to the DB (i used redis).
So now I actually build a fresh statemachine everytime a request comes in and rehydrate that object:
public String getStatesGuest(HttpServletRequest httpServletRequest) throws Exception {
StateMachine<States, Events> stateMachine = stateMachineConfig.stateMachine();
resetStateMachineFromStore(httpServletRequest.getSession().getId(), stateMachine);
return convertToJson(buildGetStateResponse(stateMachine));
}
It still is very performant, I was testing with around 30 reqs/s and still got a median of 12ms. (Docker with 2 Cores for spring boot, 1 Core for redis).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm creating a program that requires some options values to be set along with some paths to image files, path to a SQLite database, some information about the text on various buttons, information about which database to use (SQLite / MySQL for example), etc.
So far, I had a helper class in which I made everything static and I accessed it from everywhere in the program, but it was becoming a mess and I read that this is sort of bad practice since it doesn't follow object-oriented programming guidelines.
So what I did is make that class a singleton with its reference in my controller object. To access my options, I now call controller.getOptionName instead of calling Helper.getOptionName directly.
I have a feeling I'm approaching this the wrong way, especially because from what I've read, if many of my objects depend on a single class (the helper class), I'm not separating everything enough.
I don't know what I should be doing instead, is there a "standard" on where to keep all my options? I thought about using a XML file or something along those lines, but I'm going to end up having to access it from everywhere anyway, so it feels like this would create the same problem.
The Problem: Configuration Sprawl Over time, programs gain features and options. When they connect to external systems and services (e.g. databases, event brokers, cloud/web services), they must also keep a growing set of configs and credentials for those services handy.
The traditional places to store this information at runtime are global variables and OS environment variables. Both suck.
Config data logically is "global environment" or context in which the app is running, but you can't easily depend on either global or environment variables.
The other traditional mechanism, config files--whether XML, INI, .properties, or whatever--help store config data between runs, but do nothing to organize configs/options for the program code, or during its execution.
You can clean things up a bit by making options into properties of your application's classes. This is the traditional "next step." Unfortunately, it can take a lot of up-front "what goes where??" thinking. IMO, more than it's worth. Even if you get those choices right, it won't last. If you have a reasonably feature-ful app, the number of options and settings will become overwhelming over time. You'll spend a lot of time hand-coding defaults and options in object constructors and the arguments/code of other methods. Trying to perfectly partition configurations among classes not only expends effort, it can lead to highly interdependent classes. So much for clean encapsulation!
I've banged my head against this particular wall often, especially when aiming for code that has "reasonable" or "intelligent" defaults and behaviors for everything, that allows users to override defaults at any time, and that presents a simple interface that doesn't require understanding the complete interplay of app classes and components to use its services.
Solution: Delegate to a Config Object The best solution I've found is to encapsulate option/config data into its own designated object. A fancy way of describing this pattern: For configuration, settings, and option data, use delegation rather than inheritance or composition.
How you build a config mapping depends on the language you're working in. In many languages, constructing your own Config object gives you a nice "look":
if opts.verbose:
print "..."
which I find more readable than the more explicit "getter" opts.get("verbose") or "indexer" opts['verbose'] ways of accessing a property. But you usually don't have to make your own Config class, which basically is just a mapping.
● The Easy Way ● Use a generic mapping: e.g. in Python a dict, in Perl a %hash, in Java a Dictionary or HashMap. Even better, there are extensions of these designed for, or especially suited to, configuration data. In Python, e.g., I use stuf and TreeDict for their simple dot-access and other nice properties. In Java, Properties is a similar specific-for-configs extension. E.g.:
from stuf import stuf # stuf has attributes!
opts = stuf(
show_module=False, # comment explaining what show_module means
where=True, # ...
truncate=False, # ...
everything=False, # ...
allvars=False, # ...
allkeys=False, # ...
yaml=False, # ...
on=True, # ...
ret=None, # ...
)
if opts.truncate:
...
This way, all your config and option data is in one place, neatly accessible, and clearly delineated from all of the other program, class, instance, and function/method data it's used side-by-side with. This helps maintain clarity over time, as the program evolves. You can quickly determine "Is this part of the core data? Or is it related to the context in which the core data is being processed?"
To make things even better, if you pre-load config data from a config file, load or copy those values directly into your config object. And if you take arguments from the command line, load or copy those values directly into your config object. Now you have one unified source of all the "what does the user want me to do, with what options and settings?" information.
TL;DR - 90% of apps or services are just fine with a simple config/options mapping. Everything that follows is for advanced use cases. Because this was a design/patterns question, here's why this approach isn't a one-off, but extends to successively more sophisticated/intricate use cases.
● Per-Instance Config ● You can have multiple levels of config/option data. The most common use for this would be defaults set at a class or module level, then potentially different options for each instance. A server app might have an instance per user, with each user/instance needing its own customized settings. The config map is copied at instance creation/initialization, either automatically or explicitly.
●● Multiple Config Objects ●● You can partition config/option data into several config objects, if that makes sense. For example, you might partition options for data retrieval from those for data formatting. You can do this at the start of the design, but need not. You can start with one monolithic config object, then refactor over time (generally, as you start to refactor the underlying functions). Obviously you don't want to "go crazy" adding config objects, but you can have a few without adding much program complexity. If you partition config objects, you can proxy multiple config "domains" through a single API--giving you quality information decomposition internally, but a very simple outward appearance.
◆ Chain Gang ◆ More elegant than copying config data per instance: Use chainable or hierarchical mapping (e.g. in Python, ChainMap) that lets you "overlay" the values of one mapping with those of another (similar to "copy-on-write" schemes, or "union" and "translucent" file systems). Instance options then refer directly to class/default options--unless they are explicitly set, in which case they're instance-specific. Advantage: If class/default/global settings are changed during program execution, subsequent instance method invocations will "see" the changed defaults and use them (as long as they haven't been overridden at the instance level).
◆◆ Transient Config ◆◆ If you need configs/options changeable "on the fly"--say for the scope of a given method invocation--the method can extend the instance option chained mapping. In Python, that's what ChainMap.new_child() does. It sounds complicated, but as far as the method code is concerned, it's drop-dead-simple. There's still just a single config object to refer to, and whatever it says is the option, use it.
◆◆◆ Arbitrary Duration Overlay ◆◆◆ There's nothing magical about the temporal scope of method invocation. With the proper setup, any level of configuration can be transiently overlaid for as long as needed. For example, if there's some period during program run you'd like to turn on debugging, logging, or profiling, you can turn that on and off whenever you like--just for certain instances, or for all of them at once. This hors catégorie usage requires a Config object slightly beyond stock ChainMap--but not by much (basically just a handle to the chain mapping).
Happily, most code doesn't come close to needing these "black diamond" levels of config sophistication. But if you want to go three or four levels deep, delegating to separate config objects will take you there in a logical way that keeps code clean and orderly.
I would recommend placing your options into some sort of file (whether it be xml or a .properties) especially if the values can change (such as a database username, etc). I would also say that you can break up these configuration files by component. Just like you break up your code, the components that need database information likely do not need image paths. So you can have a file for database info, image path info, etc. Then have your components load the file that they need.
In the java-specific case, you can put these files on your classpath and have your components reference them. I like using .properties files because java has a nice class, Properties, for dealing with them.
So here's a tiny example for an image provider that gives you a BufferedImage, given the filename.
image.properties
icon.path=/path/to/my/icons
background.path=/path/to/my/backgrounds
Make sure this file is on your classpath. Then here's my provider class
public class ImageProvider {
private static final String PROP_FILE = "image.properties";
private static final String ICON_PATH = "icon.path";
private Properties properties;
public ImageProvider() {
properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream(PROP_FILE));
}
public BufferedImage getIcon(String icon) {
return ImageIO.read(properties.getProperty(ICON_PATH) + icon);
}
}
times when configuration was kept in static variables or when every component access them independently has ended long ago. since then mankind has invented IoC and DI. you take a DI library (e.g. spring), use it to load all the configuration (from files, jndi, environment, user, you name it) and inject it to every component that needs it. no manual resource loading, no static configuration - it's just evil
After my research and discussion here I decided I need to set the same name for threads on different JVMs which belong to the same control flow in the distributed system. Threads are created e.g. by RMI. Is it possible to set name when thread is created in that way?
There's no automatic means to transfer this info from client-to-server.
It sounds like you want/need some sort of Context object set up on the client (per-thread?) and passed as a method argument to your RMI servers. That Context object could contain not just the thread-name, but perhaps also other info like the calling process pid etc.
You'd then have to use that Context object to set thread-names etc. accordingly via Thread.setName() once it's been passed across the wire. Going forwards, you could set up context-specific info in your logging framework using this (e.g. using Log4j nested diagnostic contexts)
The use of aspects to automate this further is left as a further exercise for the reader :-)
The Thread class has a static method to setName(String). If you can have your threads, wherever they come from, running that method, you should be good to go. These guys had similar issues with Tomcat related threads.
I need to create a variable number of these based on a configuration value, the intention is to have multiple consumers where each corresponds to a physical resource that can only be used by one thing at a time to process the message.
I implemented a container that manages multiple instances of DefaultMessageListenerContainer(s) which it creates based off of a prototypical instance if the listener. Based on a system property (a # value), a number of listeners are created and the queues they listen to are numeric "my.Queue" + ordinal number. This could obviously be modified to look up the queue names if necessary. That being said, this is not a dynamically expanding/contracting list of listeners. They are created at the beginning, although I think you could use this as a starting point to make it more dynamic if you wish to.
I wrote a pretty rudimentary unit test and a very rudimentary implementation (no multithreading taken into consideration), and it appears to work.
The maven project can be downloaded here -
http://dl.dropbox.com/u/7812537/StackOverflowMultipleListeners.zip
BTW - there's an interesting thread here - http://forum.springsource.org/showthread.php?t=69604
I think there could be a way to do this by extending a generic bean factory but i'm not sure what your requirements are.
I have a servlet, and that servlet uses a .net web service to perform some function. To do this, I created the webservice client in Netbeans using the "jax-rpc" style client.
Let's say that my service name is "Tester". Then two of the generated classes are called "Tester", and "TesterSoap".
To get a reference to the web service, I need to do this:
Tester t = new Tester_Impl();
TesterSoap tsoap = t.getTesterSoap();
To use the webservice, I can then do this:
tsoap.runTest();
My question is, since this is a servlet which gets executed many times, should I store the first two lines in static variables (so they only ever get executed once), or store them locally so that they execute everytime the servlet is executed?
Another way of asking the same question: is there a performance hit everytime the first two lines are called? (I'm testing everything locally so it's hard to measure).
Thanks...
If the default constructor and any of the initialization blocks of the Tester_Impl() class and the method getTesterSoap() doesn't do anything expensive (e.g. reading file from disk, loading data from DB, connecting a socket, etc, I however suppose it doesn't) then you don't need to worry about it.
You can consider declaring them as an instance variable of the class extending from HttpServlet. But, a big but, it is going to be shared among all HTTP requests, because there will be only one instance of the particular servlet class during whole application's lifetime. So if the Tester_Impl class is supposed to have a state, then it is a very bad idea to declare it as an instance variable. It would then be shared among all requests. With other words, it's not threadsafe. If you want to ensure threadsafety in servlets, then declare everything in the very same method block.
I would not optimize prematurely here. Test this out in as close to a production environment as you can (i. e. not on your local box) and see what the performance hit is. What I've done in the past is write a small shell script that hits my server with wget n times with a delay of k milliseconds and then measured the latency, possibly instrumenting the code with some timing or profiling myself (or with jvisualvm or some other profiling tool).
If you want to protect your design from a possible performance hit without doing the testing, you could use a factory to provide instances of the service client and then you could swap out singleton service clients for many of them whenever you feel like it.