Table of contents
- Recognize When an Effort is Not a Spy Mission
- When Possible, Drive on Roads
- Qualities of a Super-Spy
- Train Your Super-Spy Instincts Using Design Heuristics
- Lesson 1 Right Now - Degrade Your Implementation For Simplicity and Compatibility Reach
- When Super-Spys Make Soup, Ingredients Can’t Be Binary Considerations
- More About Mission Impossible Code Philosophy, Heuristics and Examples
Super action spies like Ethan Hunt, Jason Borne and Evelyn Salt live in an ethos of getting the job done no matter what! They complete their missions in vastly diverse conditions and in the face of the unexpected.
Super spies make use of specialized tools and techniques when available (and working), but simple and pragmatic alternatives are always top of mind. They jump out of windows, walk across moving cars, use household objects as weapons and drive cars down staircases. They are consistently fashioning situational tools of whatever is found around them. They don’t think of objects and situations as having fixed purposes - but rather that objects and situations are flexible to serve their imposed purposes.
Is it possible to write code that acts like a super spy? Over time I have adhered to a set of coding design heuristics whose parallels to super spy behaviors are an intriguing.
The Super-spy’s hard bent commitment to hyper-pragmatism is counter balanced by an equal commitment to hyper-planning. Every action, every move and every breath will be planned to a tee if and when possible. To the super-spy, planning and opportunism are not seen as two opposite ways to approach a problem, but rather as perfectly complimentary.
A super-spy’s work is never put in an art gallery, nor does it underpin the workings of some great machine. Their work is judged by results alone. While super-spies appreciate beautiful art and love excellent machines - making such things is simply not the skills they bring to bear on their work.
As a coding disposition, pragmatism first, frequently means breaking conventions of coding style, verbosity or slavish adherence to best practices - to go for what works under the most diverse conditions.
Recognize When an Effort is Not a Spy Mission
Inevitably when one speaks with passion and advocacy of a certain approach - more than a few take it as the declaration of a universal manifesto. That the principles discussed are being claimed to apply to all circumstances, for all time. I will tell you right now that I love mission impossible coding. However, that love has also attracted me (self-selected me) to a specific area of experimentation. I am a Cloud DevOps Automation Developer and as such I am constantly called upon to knit together systems and requirements that span many different technologies, contexts and layers.
I admit that super-spies have the same self-selection - they are called upon to knit together a variety of diverse requirements, equipment and people to get the job done. We all intuitively understand that James Bond is the best guy to drive the 2 million dollar super-spy car. But we also understand that Q - not James Bond - is the best one to build the spy car.
Some problems require super-spy field methods and some problems require spy car engineering methods. The methods advocated here might not only fail miserably at building spy cars, most are likely to be anti-patterns to such an effort.
When Possible, Drive on Roads
So if you find yourself repulsed by the methods advocated here because they do not stay within the constructs of a language, do not obey rules for self-documentation or because the solution does not account for proper modularity or other similar details, then, please keep building super-spy cars and weapons, because they are very important in the grand scheme!
Qualities of a Super-Spy
The rest of this series will look at how rugged and opportunistic super-spies engage their work using specific characteristics that ensure they can get the job done no matter what. Some of these are:
- minimal assumptions
- fault tolerant
Train Your Super-Spy Instincts Using Design Heuristics
Do the above characteristics sometimes conflict with one another? Yes
Is it sometimes difficult to discern which of these should be prioritized in a given situation? Yes
Despite these challenges, do these heuristics generate results? YES
A design heuristic is like a needle on a gauge - it indicates which end of a spectrum of choice to favor - all other things being equal. However, when heuristics are combined, they have competitive tensions in the overall determination of what priorities should be optimized - precisely because all other things are NOT equal when combing them. (A combined set of heuristics are more like connected points in 3D space that define a shape within which are the possible solutions)
To get better at leveraging design heuristics, one must step in and practice - feeling and resolving these tensions again and again. It is not an unnatural learning mode for the human mind and it is supported by the ideas of Agile Discovery. The rewarding result is the training of your “instincts” so that they come up with pragmatic solutions given a complex set of input criteria. Design heuristics also account for the real-world experience that many problems are solvable with multiple different solutions. An approach of rigid laws can imply that there are few solutions or one solution to a given problem.
In the spirit of working examples, a good way to learn about how they are applied in Mission Impossible Code is to take a look at this blog Mission Impossible Code Part 2: Extreme Multilingual IaC (via Standard Code for Preflight TCP Connect Testing a List of Endpoints in Both Bash and PowerShell), paying special attention to the section titled Architecture Heuristics: Requirements, Constraints, Desirements, Serendipities, Applicability, Limitations and Alternatives
Lesson 1 Right Now - Degrade Your Implementation For Simplicity and Compatibility Reach
Super-spies will quickly and purposely degrade their choices from the “best” or “purpose specific” option to older, at hand options. Don’t have a modern weapon like a gun? Use an ink pen instead!
Here is a case in point - PowerShell’s task scheduling CMDLets versus schtasks.exe. Knitting together three or more PowerShell CMDlets for scheduling a simple task is challenging - it takes hours or days the first time, but it seems to take hours or days to reliably update the same code for newly discovered requirements. In my opinion this is because the CMDLet set reflects the underlying object structures of scheduled tasks a little too directly (A place where PowerShell implementations usually hide the underlying complexity). Consequently scheduling most tasks requires creating 3 or more types of objects with CMDLets and parameters for each. To add to this, these CMDLets are not available on all versions of PowerShell and they are easy to confuse with PowerShell job scheduling CMDlets.
I’m thinking Ethan Hunt would prefer schtasks.exe - it is available on all versions of Windows and most tasks can be scheduled with a single line. For really complex scenarios an exported XML from a working task can be used to setup a new system.
Using PowerShell CMDLets:
$TaskTrigger = (New-ScheduledTaskTrigger -atstartup) $TaskAction = New-ScheduledTaskAction -Execute Powershell.exe -argument "-ExecutionPolicy Bypass -File $scriptlocation" $TaskUserID = New-ScheduledTaskPrincipal -UserId System -RunLevel Highest -LogonType ServiceAccount Register-ScheduledTask -Force -TaskName HeadlessRestartTask -Action $TaskAction -Principal $TaskUserID -Trigger $TaskTrigger
schtasks.exe is more concise to accomplish the same thing:
schtasks.exe /create /f /tn HeadlessRestartTask /ru SYSTEM /sc ONSTART /tr "powershell.exe -file $scriptlocation"
While I am aware there are ways to reduce the number of lines of the CMDLet version, the number of objects does not reduce which means condensing the lines makes the final result much more complex and challenging to build, understand and maintain. It also requires more refactoring when new requirements are discovered.
For me, this is a case where Mission Impossible coding guides me away from the preferred stance of staying within the built-in functionality of one language.
My perspective on scheduling tasks by the most pragmatic methods did not come from a single implementation attempt - I have repeatedly implemented using the CMDlets and repeatedly come up against it’s complexity challenges (both for initial build and code maintenance) and PowerShell version limitations - schtasks.exe simply does not have these problems.
The use of schtasks.exe has these super-spy benefits:
- the resultant code is simple and easy to understand.
- the resultant code has excellent back reach (ScheduledTask CMDLets are available in PowerShell V4 and later).
- when necessary, you can process schedule tasks XML which is readily exported from the task scheduler - so you can use the GUI task scheduler as an code builder for scheduled tasks.
When Super-Spys Make Soup, Ingredients Can’t Be Binary Considerations
Many conversations about technical implementation details start with “Always” or “Never” and quickly cascade into log jams - whether in one mind or in a team discussion. What if you approached creating a new soup recipe with “in” or “out” logic for all the possible ingredients instead of considering how much of each should be used? I am guessing it would be a frustrating experience and the result would likely be disgusting to eat!
Best Practices of technology frameworks are like soup ingredients - the level of each has to be tuned together with the others and with the objectives and scope of the task at hand. When multiple frameworks are involved, the tuning approach is even more important. Like making soup, the right mix is figured out by tasting the various experiments at adjusting the amount of each ingredient.
So heuristics should generally carry intents like “Generally”, “When Possible”, “All Things Being Equal”, “A First Resort”, “A Last Resort”, “First Class Consideration”, etc. instead of “Always” or “Never”.
Heuristics also allow for keeping sight of fundamentals - you can think of this as never losing sight of what a fundamental ingredient like salt does for any soup regardless of what else is in it.
This approach can help reduce architectural tensions and fuel innovative solutions whether being create individuals or teams!
More About Mission Impossible Code Philosophy, Heuristics and Examples
Back to Basics: Testable Reference Pattern Manifesto (With Testable Sample Code) - Mission Impossible Code samples are intended to be both 1) usable directly for production use and 2) a top notch pattern to use for your own innovation.