I have been developing a Online Poker Game. But I keep hitting a wall. I want to implement Awards into the system, but I want them to be dynamic. Meaning I don't want to recompile for every award I would like to add.
I have thought about using Python code for each award. Then when the server checks to see if the user qualifies for the award it runs the python script with Jython (server is in Java and Netty NIO) and if the function returns a certain value I award the award to the user. Which could work but is there maybe a more efficient technique out there that will not force me to run hundreds of python scripts each time I need to check if a user got a award.
And when are the best times to do these checks? I have tought about a hook system where I will specify the hooks like ( [onconnect][ondisconnect][chatmessage.received] ). Which also could work but feels a bit crude and I will still have to run all the scripts from the database.
If I were you, I'd have a totally separate process that grants awards. It runs perhaps once a day on the underlying database that contains all your player/game data.
Your core customer-facing app knows about awards, but all it knows about them is data it loads from the DB -- something like a title, image, description, maybe how many people have the award, etc., and (based on DB tables) who has won the award.
Your "award granter" process simply runs in batch mode, once per day / hour etc, and grants new awards to eligible players. Then the core customer-facing app notifies them but doesn't actually have to know the smarts of how to grant them. This gives you the freedom to recompile and re-run your award granter any time you want with no core app impact.
Another approach, depending on how constrained your awards are, would be to write a simple rules interface that allows you to define rules in data. That would be ideal to achieve what you describe, but it's quite a bit of work for not much reward, in my opinion.
PS -- in running something like an online poker server, you're going to run into versions of this problem all the time. You are absolutely going to need to develop a way to deploy new code without killing your service or having a downtime window. Working around a java-centric code solution for awards is not going to solve that problem for you in the long run. You should look into the literature on running true 24/7 services, there are quite a few ways to address the issue and it's actually not that difficult these days.
There are a number of options I can think of:
OSGi as described above - it comes at a cost, but is probably the most generic and dynamic solution out there
If you're open to restart (just not recompile), a collection of jars in a well known folder and spring give you a cheaper but equally generic solution. Just have your award beans implement a standard interface, be beans, and let spring figure #Autowire all the available awards into your checker.
If you award execution is fairly standard, and the only variation between awards are the rules themselves, you can have some kind of scripted configuration. Many options there, from the python you described (except I'd go for a few big script managing all awards), to basic regular expressions, with LUA and Drools in the middle. In all cases you're looking at some kind of rules engine architecture, which is flexible in term of what the award can trigger on but doesn't offer much flexibility in term of what an award can lead to (i.e. perfect for achievements).
Some comments to the answer with batch ideas:
Implementing a Dynamic Award System
That batch processes can be on separate server/machine, so you can recompile the app or restart the server at any time. Having that new awards can be handled using for example the mentioned approach with adding jars and restarting the server, also new batch jobs can be introduced at any time and so on. So your core application is running 99% of the time, batch server can be restarted frequently. So separate batch machines is good to have.
When you need to deploy new version of core app I think you can just stop, deploy and start it with maintenance notice to users. That approach is used even by top poker rooms with great software (e.g. FullTiltPoker did so, right now it is down due to the license loss, but their site says 'System Update' :) ).
So one approach for versions update is to redeploy/restart in off-hours.
Another approach is real time updates. As a rule it is done by migrating users bunch by bunch to new version. So at the same time some users are using old version, some - new. Not pretty cool for poker software were users with different versions can interact. But if you are sure in the versions 'compatibility' you can go with that approach, checking user's client version for example on login.
In my answer I tried to say that you need not introduce 24/7 support logic to your code. Leave that system availability problems for hardware (failovers, loadbalancers, etc.). You can follow any good techniques you used to write code, only you need to remember that your crucial core logic is deployed not frequently (for example once a week), and batch part can be updated/restarted at any time if needed.
As far as I understand you, you probably do not have to run external processes from your application nor use OSGI.
Just create a simple Java interface and implement each plugin ('award') as a class implementing the interface. You could then just simply compile any new plugin and load it in as a class file from your application at run-time using Class.forName(String className).
Any logic you need from such a plugin would be contained in methods on the interface.
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Class.html#forName(java.lang.String)
Related
We have a web-based system that is essentially a survey application.
Up until now we've been loading new surveys in directly into the database (as flyway migrations). This is obviously not tenable long-term, and we need to put the power to create new surveys into the hands of the admin users. One aspect of this is adding the UI so that admin users can create new surveys.
However, we want the admin users to create and test any new surveys in a test environment first before letting it loose in production. As these surveys are complex, there is a real risk that a survey that is setup in a test environment is subtly different from how someone does the setup in the production environment. My aim is to remove this risk.
My question pertains to the technical mechanism(s) we could implement so that the admin users can, on a self-service basis, "migrate" surveys from their test environment (where they've done all of their testing and verification) to the production environment - such that we have a high confidence that the migrated survey(s) will be setup identically. Applications like Moodle already have this sort of functionality built-in.
I've considered:
Allowing users to create a checksum of a survey (perhaps based on the hashcode of all the elements) so they can know that the surveys across the two environments are identical. The issue then is that it would be annoying to try and find the exact difference between the surveys on the two instances.
Writing a UI that dumps raw SQL as the export and allowing these users to just splatting it into the production database, but it's incredibly bad from so many perspectives
Constructing our own domain-specific language that describes these surveys - but writing an input/output parser just seems so complex
Dumping the data to JSON (given that it's a RESTful web app, most of this is already done) and sucking it back in
At this stage, I'm leaning towards the JSON method, but would be keen to hear any other ideas or libraries that we could easily integrate into a Spring Boot app that would assist with this process.
To be honest, solving that kind of problem by introducing independent instances sounds like a terrible idea: Not only the migration part is tricky. You will have to ensure compatibility at all times. Imagine an admin uses an outdated version or does not configure his instance correctly (every admin's dream). Even if the migration itself produces no errors the results may be different in the end (and that's what you actually want to avoid).
As I understand it, you currently look at a survey as a bulk of raw information that somehow appears in your database and then gets displayed by the application. From that point of view you obviously can't tell the difference between a test survey and a production survey.
That's why you really should extend your model!
There is much more than just a survey. There is a survey draft and/or a survey preview area, a survey creation process that users go through, a process that spins of a production survey from a draft, etc.
If you add those concepts to your application a use case like the one you described should be easy to implement (you already mentioned a planned UI, right?).
Hope I could help you. Sorry, I know it doesn't exactly answer your question.
My question without the fluff
Is Spring-Batch the right tool for converting a handful of one-off (one and done type) java projects that tend to interact with a database at some point, into their own separate "Jobs" that are part of a Spring-Batch project?
With Fluff/Background
The company I work for has several "one off" java projects that really only do one thing (either at some arbitrary time, or just whenever we tell it) and then they are done. They tend to interact with the database at some point in their lifecycle, but not necessarily at the same time.
There are a couple more projects/scripts that I'm tasked with creating, but instead of having nearly 10 different perl scripts and a few handful of jars out on our box, we would like to maybe stuff all these projects in one place and just be ran when we need to run them (ideally on a remote box via command line args). From the research I've done on Spring-Batch, it kind of sounds like exactly what we are looking for, especially the functionality described here.
I'm moderately familiar with Spring-Boot and the Spring Framework, but for some reason reading up on Jobs and the setup, the domain language seems a little foreign to me, and I just want to make sure I'm not wasting my time trying to figure this out if it's not realistic. We would like this to just be one cozy place for any current or future projects that are ran independently so that we minimize clutter on our box. Just to clarify, I keep saying projects, but from what I understand, these projects need to be converted to Jobs if they are to be part of a Spring-Batch project. Is this realistic?
(converting comments to an answer)
If things like task scheduling, transaction management, consuming data in chunks, flexibility on start/stop operations, retrying mechanisms are things you find yourself spending time into coding yourself then yes definitely take a look at Spring Batch it has robust already-implemented facilities of all of the above.
On the grander scheme of things if your application has many moving parts, consuming a lot of external resources you might as well dive into the EIP (Enterprise Integration Pattern) waters with Apache Camel and Spring Integration very solid implementations.
By your description your one-off project(s) are reasonable single-focused so the learning curve of new frameworks might not worth the while. In that case it might suffice to focus on the re-usable components of your projects and externalize them on a core/helper lib for re-usabilitly purposes if that makes sense.
I have a legacy web application sys-1 written in cgi that currently uses a TCP socket connection to communicated with another system sys-2. Sys-1 sends out the data in the form a unix string. Now sys-2 is upgrading to java web service which in turn requires us to upgrade. Is there any way to upgrade involving minimal changes to the existing legacy code. I am contemplating the creating of a code block which gets the output of Sys-1 and changes it into a format required by Sys-2 and vice versa.
While researching, I found two ways of doing this:
By using the "requests" library in python.
Go with the java webservices.
I am new to Java web services and have some knowledge in python. Can anyone advise if this method works and which is a better way to opt from a performance and maintenance point of view? Any new suggestions are also welcome!
Is there any way to upgrade involving minimal changes to the existing legacy code.
The solution mentioned, adding a conversion layer outside of the application, would have the least impact on the existing code base (in that it does not change the existing code base).
Can anyone advise if this method works
Would writing a Legacy-System-2 to Modern-System-2 converter work? Yes. You could write this in any language you feel comfortable in. Web Services are Web Services, it matters not what they are implemented in. Same with TCP sockets.
better way to opt from a performance
How important is performance? If this is used once in a blue moon then who cares. Adding a box between services will make the communication between services slower. If implemented well and running close to either System 1 or System 2 likely not much slower.
maintenance point of view?
Adding additional infrastructure adds complexity thus more problems with maintenance. It also adds a new chunk of code to maintain, and if System 1 needs to use System 2 in a new way you have two lots of code to maintain (Legacy System 1 and Legacy/Modern converter).
Any new suggestions are also welcome!
How bad is legacy? Could you rip the System-1-to-System-2 code out into some nice interfaces that you could update to use Modern System 2 without too much pain? Long term this would have a lower overall cost, but would have a (potentially significantly) larger upfront cost. So you have to make a decision on what, for your organisation, is more important. Time To Market or Long Term Maintenance. No one but your organisation can answer that.
Maybe you could add a man-in-the-middle. A socket server who gets the unix strings, parse them into a sys-2 type of message and send it to sys-2. That could be an option to not re-write all calls between the two systems.
I want to make an application in java that has a GUI and a database. I will be using MYSQL as the database and my recent experience with JavaFX has been quite pleasant so that's what I'll be using to code.
My issue is I want user access control and want to show GUI components based on who or what type of user logs in.
So let us say it's a school management system and if a teacher logs in the teacher can access his or her course and homework assignments ( via GUI of course) but not any other teacher's. If an admin user logs in he/she can make changes to student profile, etc. but nothing else.
Could someone point me in the right direction with regards to concepts, tutorials, books, sample code, etc. so I can accomplish something like this
if(user==teacher){
stage.setscene(teacherOnlyScene);
stage.show();
}
Thank you so much! Apologies if its too subjective. This is the one site that I use like 90% of the time for answers to all my programming related questions.
The scope of your question is probably too large to be successfully answered here as you are asking about a fairly sizeable and potentially complex portion of the architecture of your final system. User access systems are generally quite complex especially if they are highly configurable e.g. you can grant users privileges outside their basic group privileges etc.
Before starting to write any code have a think about what you want to achieve. You've already come up with the idea of using user groups which I think is very sensible but there are some questions you need to ask. Can users belong to multiple groups? Can permissions be assigned to users or can they only be assigned to groups? Is the administrator a special case or can it be handled as just another group?
Have a look at the way Linux handles users and groups to assign permissions. It's a very well thought out system should offer some inspiration. Additionally the JavaEE 6 documentation orangegoat linked to provides a good overview of security in Java EE (but be warned it's fairly complex).
Having said that I feel I must encourage you to consider making this a web based application rather than using JavaFX. It doesn't sound like you have any particularly complex graphical requirements and it also sounds like you want multiple concurrent access to the system / database (e.g. more than one teacher can be checking their assignments at a time).
Perhaps I'm a little biased but I think a JavaEE based web application is a better match for these requirements. The business logic and most of the complexity of the multi-user side of things would be handled well by a bunch of EJB's with all the persistence handled by JPA. The GUI would be written in JSF and PrimeFaces and the whole lot hosted on GlassFish. The real benefit of this set up is that you have a zero installation footprint which will save you a ton of time when rolling out new versions. Going the JavaEE route will probably make it more difficult for you but I feel it's the correct solution given the requirements.
I have an application that is undergoing massive rework, and I've been exploring different options - chug along 'as is', redo the project in a different framework or platform, etc.
When I really think about it, here are 3 major things I really dislike about java:
Server start/stops when modifying controllers or other classes. Dynamic languages are a huge win over Java here.
Hibernate, Lazyloading exceptions (especially those that occur in asynchronous service calls or during Jackson JSON marshalling) and ORM bloat in general. Hibernate, all by itself, is responsible for slow integration start up times and insanely slow application start up times.
Java stupidity - inconsistent class-loading problems when running your app inside of your IDE compared to Tomcat. Granted once you iron out these issues, you most likely won't see them again. Even still, most of these are actually caused by Hibernate since it insists on a specific Antlr version and so on.
After thinking about the problem... I could solve or at least improve the situation in all 3 of these areas if I just got rid of Hibernate.
Have any of you reworked a 50+ entity java application to use mongo or couch or similar database? What was the experience like? Do you recommend it? How long did it take you assuming you have some pretty great unit/integration tests? Does the idea sound better than it really is?
My application would actually benefit in many areas if I could store documents. It would actually open up some very cool and interesting features for this application. However, I do like being able to create dynamic queries for complex searches... and I'm told that Couch can't do those.
I'm really green when it comes to NoSQL databases, so any advice on migrating (or not migrating) a big java/spring project would be really helpful. Also, if this is a good idea, what books would you recommend I pick up to get me up to speed and really make use of them for this application in the best way possible?
Thanks
In any way, your rant doesn't just cover problems with the previously made (legacy) decision for Hibernate but also with your development as a programmer in general.
This is how I would do it, should a similar project be dropped in my lap and in dire need of refactoring or improvement.
It depends on the stage in your software's lifetime and the time pressure involved if you should make big changes or stick with smaller ones. Nevertheless, migrating in increments seems to be your best option in the long term.
Keeping the application written in Java for the short term seems wise, a major rewrite in another language will definitely break acceptance and integration tests.
Like suggested by Joseph, make the step from Hibernate to JPA. It shouldn't cost too much time. And from there you can switch the back-end to some other way of storage. Work towards a way of seperating concerns. Pick whatever concept seems best, some prefer MVC while others might opt for CQRS and still others adore another style of segmentation/seperation.
Since the JVM supports many languages, you can always switch to any of those or at least partially implement functionality in more dynamic languages. This will solve part of the problem where you keep bumping into the "stupidity" of Java, while still retaining the excellent optimizations of current JVMs at runtime.
In addition, you might want to set up automatic integration tests... since the application will hopefully never be run from your IDE, these tests will give you honest results.
Side note: I never trust my IDE to get dependencies right if the IDE has capabilities to inject its own libraries into my build or runtime path.
So to recap in short: small steps; lose Hibernate and go more abstract to JPA; if Java becomes stupid, then gradually switch to a clever language. Your primary concern should be to restructure the code base without losing functionality, keeping in mind to have an open design which will make adding interesting and cool features easier later on.
Well, much depends on things like "what exactly are the pain points with Hibernate?" (I know, you gave three examples...)
But those aren't core issues over the long haul. What you're running into is the nature of a compiled language vs. a dynamic one; at runtime, it works out better for you (as Java is faster and more scalable than the dynamic languages, based on my not-quite-exhaustive tests), but at development time, it's less amenable to just hacking crap together and hoping it works.
NoSQL isn't going to fix things, although document stores could, but there's a migration step you're going to have to go through.
Important: I work for a vendor in this space, which explains my experience in the area, as well as the bias in the next paragraph:
You're focusing on open source projects, I suppose, although what I would suggest is using a commercial product: GigaSpaces (http://gigaspaces.com). There's a community edition, that would allow you to migrate JPA-based java objects to a document model (via the SpaceDynamicProperties annotation); you could use JPA for the code you've written and slowly migrate to a fully document-oriented model at your convenience, plus complex queries aren't an issue.
All of those points are usually causing problems due to incompetence, rather than hibernate or java being problematic:
apart from structural modifications (adding fields or methods), all changes in the java code are hot-swapped in debug mode, so that you can save & test (without any redeploy).
the LazyInitializationException is a problem for hibernate-beginners only. There are many and clear solutions to it, and you'll find them with a simple google or SO search. And you can always set your collections to fetch=FetchType.EAGER. Or you can use Hibernate.initialize(..) to initialize lazy collections.
It is entirely normal for a library to require a specific version of another library (the opposite would be suspicious and wrong). If you keep your classpath clean (for example by using maven or ivy), you won't have any classloading issues. I have never had.
Now, I will provide an alternative. spring-data is a new portfolio project by springsource, that allows you to use your entities for a bunch of NoSQL stores.