In our Java app, using spring-aop, in order to collect certain statistics, we have two around-advices which get hit consecutively per request, like this: advice-A ->proceed-> advice-B ->proceed-> advice-B -> advice-A
To avoid writing to the DB twice, we want to share the information captured by the second advice with the first, and write it all to the DB after the proceed in the first (outer) advice.
How can this be done without using nasty things like static classes with ThreadLocals?
I read about perthis and pertarget, but if I understand it correctly that would only be useful if our service beans are request-scoped. Then you could wire one advice into the other and share information that way.
Related
We are running a setup locally where we start two instances of an Axon application. The following properties are set in application.yml:
axon:
eventhandling:
processors:
SomeProcessorName:
initialSegmentCount: 2
threadCount: 1
mode: TRACKING
So both nodes have a single thread and they should each process a segment. They both connect to AxonServer. How do the two instances coordinate segment claims?
If I start both of these applications using an in-memory database, I can see in AxonServer that they both attempt to claim segment 0 and that segment 1 is claimed by neither. (We get a duplicated claim/unclaimed segment warning). If they connect to the same database, this does not happen, instance 1 claims segment 0, instance 2 claims segment 1.
Am I then correct in assuming that identical processors have to share a database in order for this to work properly? I can't find this information immediatly in the reference docs.
Does this then also mean that if I would hypothetically want to replicate a projection model for performance reasons (e.g: database server in the US and another one in the EU), this would not work properly?
To clarify: I would want both databases to build an identical query model that could both be queried separately. As it is right now (assuming that we could run two nodes on two databases), node 1 would only process events for segment 0, node 2 would only process events for segment 1. If I understand this correctly, this means that both databases only contain half of the information of the query model.
So in order to pull this off, I would have to create another near-identical codebase, with the only difference being the processor name?
I think I can give some guidance in this area.
Axon Server does not provide coordination between Tracking Tokens of TrackingEventProcessor at this point in time.
Thus, coordination of this part is purely in your application environment, or differently put, with the Axon Server client.
The most pragmatic approach would be to share the underlying storage solution for your TokenStore between both application; so your assumption on this part is correct.
Current implementations of the TokenStore are indeed database-based - nothing stops you to come up with a distributed solution of this though, as this is all open source and freely adjustable.
I do not completely follow your hypothetical suggestion that:
Does this then also mean that if I would hypothetically want to replicate a projection model for performance reasons (e.g: database server in the US and another one in the EU), this would not work properly?
Well, this can work properly, but I think the segmentation of a given TrackingEventProcessor it's TrackingToken is not the way to go in this part.
This solution is intended to share the work load of updating a single Query Model.
The 'work load' in this scenario is the Event Stream by the way.
If you're looking to replicate a given Query Model by means of reading the Event Stream, I'd indeed suggest to have a second TrackingEventProcessor, which has an identical Event Handling Component underneath.
Note that this should not require you to 'replicate the code base'.
You should merely need to register two Event Handling Components to two distinct TrackingEventProcessors.
If you are using Spring Boot as configuration, all this is typically abstracted away from you. But if you take a look at the EventProcessingConfigurer, you should be able to find a fair API describing how to achieve this. If things aren't clear in that area, I'd suggest a different issue should be introduced, as the topic somewhat diverges from the original question.
Hoping this is sufficient for you to proceed #MatthiasVanEeghem!
I try to figure out the best solution for a use case I'm working on. However, I'd appreciate getting some architectural advice from you guys.
I have a use case where the frontend should display a list of users assigned to a task and a list of users who are not assigned but able to be assigned to the same task.
I don't know what the better solution is:
have one backend call which collects both lists of users and sends them
back to the frontend within a new data class containing both lists.
have two backend calls which collect one of the two lists and send them
back separately.
The first solution's pro is the single backend call whereas the second solution's pro is the reusability of the separate methods in the backend.
Any advice on which solution to prefer and why?
Is there any pattern or standard I should get familiar with?
When I stumble across the requirement to get data from a server I start with doing just a single call for, more or less (depends on the problem domain), a single feature (which I would call your task-user-list).
This approach saves implementation complexity on the client's side and saves protocol overhead for transactions (TCP header, etc.).
If performance analysis shows that the call is too slow because it requests too much data (user experience suffers) then I would go with your 2nd solution.
Summed up I would start with 1st approach. Optimize (go with more complex solution) when it's necessary.
I'd prefer the two calls because of the reusability. Maybe one day you need add a third list of users for one case and then you'd need to change the method if you would only use one method. But then there may be other use cases which only required the two lists but not the three, so you would need to change code there as well. Also you would need to change all your testing methods. If your project gets bigger this makes your project hard to update or fix. Also all the modifications increase the chances of introducing new bugs as well.
Seeing the methods callable by the frontend of the backend like an interface helps.
In general an interface should be open for extension but closed on what the methods return and require. As otherwise a slight modification leads to various more modifications.
I have a lot of existing data in my database already, and want to develop a points mechanism that computes a score for each user based on what actions they do.
I am implementing this functionality in a pluggable way, so that it is independent of the main logic, and relies on Spring events being sent around, once an entity gets modified.
The problem is what to do with the existing data. I do not want to start collecting points from now, but rather include all the data until now.
What is the most practical way to do this? Should I design my plugins in such a way as to provide for an index() method, which will force my system to fetch every single entity from the database, send an EntityDirtyEvent, to fire the points plugins, for each one, and then update it, to let points get saved next to each entity. That could result in a lot of overhead, right?
The simplest thing would be to create a complex stored procedure, and then make the index() call that stored procedure. That however, seems to me like a bad thing either. Since I will have to write the logic for computing the points in java anyway, why have it once again in SQL? Also, in general I am not a fan of splitting business logic into the different layers.
Has anyone done this before? Please help.
First let's distinguish between the implementation strategy and business rules.
Since you already have the data, consider obtaining results directly from the data. This forms the data domain model. Design the data model to store all your data. Then, create a set of queries, views and stored procedures to access and update the data.
Once you have those views, use a data access library such as Spring JDBC Template to fetch this data and represent them into java objects (lists, maps, persons, point-tables etc).
What you have completed thus far does not change much, irrespective of what happens in the upper layers of the system. This is called Model.
Then, develop a rule base or logic implementation which determines, under what inputs, user actions, data conditions or for all other conditions, what data is needed. In mathetical sense, this is like a matrix. In programming sense, this would be a set of logic statements. If this and this and this is true, then get this data, else get that data, etc. This encompasses the logic in your system. Hence it is called "Controller".
Do not move this logic into the queries/stored procedure/views.
Then finally develop a front-end or "console" for this. In the simplest case, develop a console input system, which takes a .. and displays a set of results. This is your "view" of the system.
You can eventually develop the view into a web application. The above command-line view can still be viable in the form of a Restful API server.
I think there is one problem here to be considered: as I understand there's huge data in the Database so the idea to create only one mechanism to calculate the point system could not be the best approach.
In fact if you don't want to start collecting points but include all the data, you must process and calculate the information you have now. Yes, the first time you will run this can result an overhead, but as you said, you need this data calculated.
By other hand you may include another mechanism that attends changes in an entity and launches a different process capable of calculate the new pointing diffence that applies to this particular modification.
So, you can use one Service responsible of calculate the pointing system, one for a single entity and another, may be longer to finish, capable of calculate the global points. Even, if you don't need to be calculated in real-time you can create a scheduled job responsible of launch it.
Finally, I know it's not a good approach to split the business logic in two layers (Db + Java) but sometimes is a requirement do it, for example, if you need to reply quickly to a request that finally works with a lot of registries. I've found some cases that there's no other option than add business logic to the database (as a stored procedures, etc) to manage a lot of data and return the final result to the browser client (ex: calculation process in one specific time).
You seem to be heading in the right direction. You know you want your "points" thing decoupled from the main application. Since it is implied you are already using hibernate (by the tag!), you can tap into the hibernate event system (see here section 14.2). Depending upon the size/complexity of your system, you can plugin your points calculations here (if it is not a large/complex system), or you can publish your own event to be picked up by whatever software is listening.
The point in either design approach is that neither knows or cares about your point calculations. If you are, as I am guessing, trying to create a fairly general purpose plugin mechanism, then you publish your own events to that system from this tie-in point. Then if you have no plug-ins on a given install/setup, then no one gets/processes the events. If you have multiple plug-ins on another install/setup, then they each can decide what processing they need to do based upon the event received. In the case of the "points plugin" it would calculate it's point value and store it. No stored proc required....
You're trying to accomplish "bootstrapping." The approach you choose should depend on how complicated the point calculations are. If stored procedures or plain update statements are the simplest solution, do that.
If the calculations are complicated, write a batch job that loads your existing data, probably orders it oldest first, and fires the events corresponding to that data as if they've just happened. The code which deals with an event should be exactly the same code that will deal with a future event, so you won't have to write any additional code other than the batch jobs themselves.
Since you're only going to run this thing once, go with the simplest solution, even if it is quick and dirty.
There are two different ways.
One is you already know that - poll the database for for changed data. In that case you are hitting the database when there may not be change and it may slow down your process.
Second approach - Whenever change happens in database, the database will fire the event. That you can to using CDC (Change Data Capture). It will minimize the overhead.
You can look for more options in Spring Integration
We are trying to implement some flow control in Play, kind of a wizard with several steps. What is the best practice to do it in Play?
Requirements we have:
Should allow multi-step flows, like step1 -> step2 -> step3 -> step4 -> finish
Should be able to change order or steps depending on context, so if user selects a checkbox on step2, flow should be step1 -> step2 -> warningStep -> step5 -> finish
Ideally needs support for "Back" button to return between steps
The problem we have is that any single step in flow doesn't know where it should redirect next and since Play session is very simple, it won't help here much.
Here is the solution we currently have:
Store Flow steps in database in user object with #OneToMany public List<FlowStep> flowSteps
Provide methods in user model to add/remove/skip and change order of flow steps stored for this user
Implement steps normally, with form action leading to "doStep3" controller etc
Implement "Flows" controller that uses #Before and #After interceptors to correctly redirect to next step after current step is processed and no validation errors found
Added Flows.next() controller that redirects to next step (used for "Skip" button href)
What are the disadvantages of this solution? Is there any better way (maybe some Play built-in methods) to improve it?
What you want is a finite state machine. To implement it, you'll need a class that knows all the possible transitions between steps. Then you can provide to it the current step and any relevant input, and it will return the output (where the output is the view to render next).
Then you use render to redirect the user, as in:
render("my/view/path.html", myparams);
This is not the only option, and storage of the transitions will depend on how complex you need them (can be hardcoded for simple scenarios, maybe stored in database for more complex ones), but it should work.
As Play is stateless you'll need to keep the information in the database (for complex scenarios where you need to take in account information for several steps) or, if the relevant togles are just a few, store them in the cookie itself.
I would avoid using #Before/#After as you are coupling the state machine to the controller. Ideally you want them to be idnependent, with the state machine returning only transitions that you can translate later into view paths. That will simplify changing transitions.
If the scenario is not extremely complex, I would not even bother to store them in the database. If you want it reusable and extremely flexible, then do it, otherwise it may be simpler to just "hardcode it".
Did you check this section in the Play documentation (a very quick read):
http://www.playframework.org/documentation/1.2.4/model#stateless
It lists the options you have for exactly what you are asking.
You can try to use Play Cache mechanism as pseudo session to store the validated steps instead of handling in the database. Using Play Cache would be a simpler solution
Let say that there are events that may occur (are less likely), but they should be registered. This is data that one just need for tuning ... to see what has happened and what needs to be changed and improved.
Typically this is done in catch blocks when exception is thrown or just if some if condition passes.
I don't want to write shell scripts and collect data from logs so I can either use DB and create a table for every context, which is possible in most cases, but it is extremely inconvenient for maintenance and refactoring in further development. Especially because the data will by typed as RDB is used. Mostly the only shared data is userId, time, component and varying data like fileId, fileSize || elementsCount, count deviance || etc.
Or I can use some nosql store for that, which is also a little overkill to do that just because of this, but as the data has rather type free nature, I guess it would be more convenient.
Could you please explain how you do it ? How is this even called ? I think that JMX doesn't deal with this scenario. Spring AOP or AOP in general deals only with the distributed nature of this.
It sounds like you have two separate questions:
How should I capture certain events in the first place?
What should I do with the events once I've captured them?
Regarding 1, yes, AOP is a pretty common solution for capturing events. I'm not sure what you mean by "AOP in general deals only with the distributed nature of this". There's nothing distributed about AOP. You haven't told us enough about your application for anybody to say how to integrate AOP as easily as possible, etc, but lots of information is available online.
Regarding 2, how much data are we talking about? How much information do you want to store per event? What's similar/different about each message? I'd probably take the following approach:
Figure out how much data you're going to save during any given second, minute, hour, day, etc. If it's small enough to fit into one of your existing databases, then don't complicate your environment by introducing a new technology.
Can the data be loaded synchronously? If yes, then that's easy. Otherwise, I probably would log the data, and consolidate it periodically with a simple ETL script. This probably will be a whole lot easier and cheaper than setting up a new nosql store that you don't have in production now.
Decide what data you want to keep. It probably will look something like: id, type, timestamp, source (e.g. server or instance of the application), details. Details should be type-specific.
Decide what types of queries or reports you want to run on the data.
Do you need to structure the type-specific stuff so that specific queries are possible? Can you keep the type-specific stuff in an XML or JSON document, and only parse them in type-specific reports? Or, do you need to refer to type-specific stuff in the queries themselves? Type-specific details can make queries hard, but a nosql database such as mongodb might actually help here.
Figure out your data retention policy. You probably need to clean up old data at some point. This might affect the design of your storage.