4

So I am working with a customer who has an older application that has quite a few interesting quirks. Among other things, it has its own code version system for business functions, by storing the entire algorithm version in a database. The data is then retrieved and compiled on request (this is a web application, and yes, it compiles a ton of code each time you try to buy something).

For obvious reasons, this isn't exactly fast. I am looking into migrating the code into normal code projects, but as you can imagine, this creates an interesting challenge in regards to versions of the algorithms.

It is a business requirement that old quotes / deals that are up for review must use the same algorithm that was used when it was first created. Said quote should then be able to recalculate, with changed input etc (so we can't just store the results).

How would you approach this problem? They are having such massive issues in production now that I have simply decided we will create a hot-fix by moving all the code to actual libraries and calling functions with name versioning (someAlgortihm6Jun2014 or whatever) which will solve the problem of immense bandwith use and wasted compilation time, but it is far from elegant.

While I will be looking to implement much larger architectural changes in the future, for now I am simply looking for a good way to maintain multiple versions of the same algorithm in static code, without resorting to this naming convention. Thoughts?

  • 1
    A suggestion to improve your question: include somehow the compilation step in the title of your question; it is the main obstacle you are facing. Something like "Design to switch between versions of compiled algorithm/code"? Otherwise, "multiple versions of same strategy" can be maintained by just using "if/else" :) – logc Jun 24 '14 at 12:13
  • Actually, why do you think your current solution is "far from elegant"? – Doc Brown Jun 24 '14 at 12:25
  • @DocBrown Ten functions with the same name (especially if they are long) with added versioning postfix will quickly make it hard to distinguish between them, I think. I don't want to use if/else/switch/case, this will make it horrendously cluttered as the code is already fairly big (a lot of the functions suffer from poor maintenance and are already more than five hundred lines in size) – Marius Brendmoe Jun 24 '14 at 12:35
  • Why doesn't just a plain old strategy pattern resolve the issue? – Sign Jun 24 '14 at 13:51
  • 1
    You could encapsulate the algorithm versions in Strategy pattern classes. This doesn't magically eliminate the if's though, you still have to inject the right strategy depending on the entity. This could be done at O/R mapping time depending on some fields in the DB. – guillaume31 Jun 24 '14 at 13:55
1

As far as I understand you, there is no maintenance for those older versions to do - only for the newest version (changing of older version is forbidden, right?). That means, even if the function names become very technical after versioning, this should not be too much of a problem, since you never have to touch that code again.

You need to store the functions in compiled form out of the database, so the obvious place is in an assembly of your application. Put the older versions of those functions in a separate assembly, as part of the versioning process, so you get them out of your way when you make changes to the newest version.

Use a rigorous naming scheme for your functions appropriate to your business requirements (there must be also a way for your users to distinguish between older and newer functions as well - why not just name your functions with a kind of prefix according to your users scheme of "doing things")? If the criteria is a date, then it is date which gets part of your function name - if that's used in the production process, it will be the best you can come up with. And instead of a big pile of if/else/switch/case, use a dispatch table.

If each of your "functions" are is not really just one function, but a bunch of functions and data, you may also consider to encapsulate them in command or strategy objects (as some commenters have suggested). That shifts the versioning and naming problem from the function level to the class level. The general idea keep the same.

It may be also of interest how and how often new versions of your functions are created. Is this done just manually by a developer? Then the versioning of a function can probably done manually, too (maybe supported by some self-made tools, renaming the function in stake, moving the source code to the "versioned functions project" and extending your dispatch table).

There is another option, of course: keep everything in the database where it is now, but cache the compiled output locally. So before getting the source code and compiling the same function again, check if there is already a locally cached pendant available, and if so, use the copy from the cache (you should make some checksum test to assure the local compiled copy is related to the source code in your db). This will not prevent compiling and database access completely, but it may probably be the solution you are looking for. And its has the advantage, that you can easily deploy new functions or function versions into production without deploying the full application.

  • there are quite a few interesting issues that makes it hard to quickly implement caching (there already is a faulty one in place, among other things). A lot of great input here though.. I may just consider designing it to use strategies and simply select from strategy objects on the server depending on rows, but for now I will stay stick with the version number solution I guess, as the db changes required would be significant. – Marius Brendmoe Jun 25 '14 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.