Last Build Date: Sat, 25 Feb 2017 09:35:19 GMT
Fri, 24 Feb 2017 11:00:00 GMT
"Sure, it's a bit expensive, but hey, where else can you find a place with a huge outside baloney?" Keith S. wrote.
"People think that nobody plays Candy Crush any more," writes Maddie, "It seems their testers agree."
Alex writes, "Well, looks like Facebook is testing in production again."
"These empty groups in Facebook Workplace are definitely where things take off...any minute now..." Björn E. wrote.
Janez writes, "Seeing a stack trace while driving hits you a little differently than when you're at your desk."
"Ok, name parsing can be tricky, but sometimes it's best to just not to try so hard," wrote Geoff G.
Peter K. writes, "Now we know that XP is hiding out in the French Alps."
Thu, 23 Feb 2017 11:30:00 GMT
For every line of code that ends up in software the general public sees or interacts with, for every line in your Snapchats and Battlezone: Call of Honor Duty Warfare, there are a thousand lines of code written to handle a supply chain processing rule that only applies to one warehouse on alternating Thursdays, but changes next month thanks to a union negotiation. Or it’s a software package that keeps track of every scale owned by a company and reminds people to calibrate them. Or a data-pump that pulls records out of one off-the-shelf silo and pushes them into another.
That’s the “iceberg
Tue, 07 Feb 2017 11:30:00 GMTWe've all built table driven software. In your engine, you put a bunch of potential callbacks into some data structure, perhaps a map, and call the relevant one based upon some key value. Then the calling logic that uses the engine has some structure that holds the key(s) of the method(s) to be called for some context. If you change the key(s) for a given context, then the corresponding method(s) that get called change accordingly. It's neat, clean, efficient and fairly simple to implement. At least you'd think so. Unless you run into one of those folks who believes that everything, and I mean everything belongs in the database. About 15 years ago, a mid level developer was tasked with creating a table-driven mechanism to call methods based upon values returned from a query to a remote system in real time. He took the phrase "table driven" literally. After I was hired, I was tasked with diagnosing and fixing the performance problems that were weighing down the application. This developer spent a little time explaining his table driven software to me (minus the fact that it was actual DB tables) and that this was highly efficient and couldn't be the source of the performance issues. There was a single stored procedure call named Engine which took as a hard wired argument the name of the method to call, and an arbitrary list of up to 100 pairs of parameter type and value strings. It would then look up the specified method name to see if it existed, and grab the user id from the environment and look up whether the user had permission to call said method. If so, it would parse the arguments until it hit a null, and based upon the specified types, verify that those types matched the ones configured for the specified method, build up a string representing the method call, exec it, grab the results, and spit them back as a delimited string in a single output parameter. It looked something like this: Procedure Engine(methodName IN varchar2, resultData OUT clob, exceptions OUT clob, param1Type IN number Default null, param1Val IN varchar2 Default null, ... param100Type IN number Default null, param100Val IN varchar2 Default null) IS Begin ... End; To accomplish this magic, all of the callback-method logic had to be configured inside the database as Java stored procs so that it was accessible to be called from the engine stored proc. For added fun, exceptions were converted to text fields (to hold the stack dumps) and passed back as an additional output parameter. Your code would then be responsible for manually checking to see if an exception had been thrown. If so, it could then throw a generic exception with the text of the actual exception that was thrown inside the code in the DB as the message field of the new exception. Thus, you would build up a stored procedure call to the Engine in your Java code, call it, and in the database, the engine would pick apart the parameters, construct an SQL string representing the targeted method call, call it as a Java stored proc inside the DB, grab any returned results or exceptions and stringify them, grab the results in the usual way in your Java application, then manually check for and throw an exception if one occurred, and if not, pick apart the results-string. The table(s) that controlled this table-driven engine were as follows: DB Table AppUserPermissions -- permissions, by user, to call specific methods id number(38,0) -- sequence/PK userName varchar2(32) not null -- name of user executing the program methodId number(38,0) not null -- FK to AppMethods.Id that UserName may execute DB Table AppMethods -- list of methods callable via the table driven engine id number(38,0) -- sequence/PK methodName varchar2(255) [...]