Gated Community Pattern

Problem: Junk gets into a system's calculating innards and causes all sorts of gastric disturbances.

Solution: Gate the data through a set of methods that purify the data so that the rest of the system can then work unhindered by corruption.
This would be a set of methods that all operate on the same set of data. The data has been meticulously checked before being submitted to the functions on the "safe" side of the gate. All of the naive functions in the gated community act on the data without any kind of error or bounds checking because that has already been done for them. Also, no possible combination of processing within the community can produce data that would cause any of the bounded functions to kak. Does this sound reasonable? I sure hope so, because I've done a bunch of EmbeddedSystems this way. -- MartySchrader

I HaveThisPattern. My code contains an object model representing things in a world, and the calling code may not be well written or even trusted. The object model's public API validates all the parameters given to it, but then calls a load of package methods to get the task done, none of which implement parameter checks. This is not a Facade because there is more than one object which is used by client code - it's simply use of the Java package protection mechanism. To validate the caller's permissions, the public methods are acting as the clients for a class containing many BouncerPattern methods (my SecurityManager implementation). -- TorneWuff
This kind of gate isn't entirely possible in the general case without actually performing the same or equivalent processing on the 'unsafe' side of the gate (due to potential for undecidability). However, there is still a vast array of cases where it is reasonable.

No, not so. Note that the above statement says that no possible combination of processing on the safe side can produce results that exceed the bounds. This is how you limit uncertainty and potential risks.

However, if you have a case where some combination of "safe" data and the processing of that data could exceed the bounds then you need to have another test. There's no real pattern for that; it has to be decided through bounds analysis.
What I really want is an AutomaticGate? - An implementation of GatedCommunityPattern where the 'set of validation methods' is both computed automatically and applied automatically to all 'untrusted' command/data sources... and, importantly, NOT applied to trusted sources of data (as an optimization), which includes code inside the 'gate'. (In the broad scope, 'trusted' command/data sources can also include some external processes that meet certain criteria - machine-local, used same compiler, statically typechecked I/O, etc.. as you'd potentially see for first-class processes or a SingleLanguageOperatingSystem.)

One possible approach towards this AutomaticGate? would be to use SoftTyping where failed proofs are pushed as far as possible towards the outer edge of the exported interface, allowing a pair of interfaces (proxy 'gated' interface, and the trusted interface that are accessible only via the gated interface and through a trusted link/loader). For other security issues (CapabilitySecurity?, for example), the type system might be further extended to include descriptions of required access rights (at least for comms/port types).

Yeah, I like that. The idea of using a first class function to deal with data that you know is safe to process makes a lot of sense. The idea of autogenerating all the function calls and argument lists is a head scratcher, though. And are you talking about fuzzy matching the data/processes that potentially exceed the boundaries, or just the ones where they've actually exceeded bounds? That becomes a run-time operation involving all kindza smarts that we've not discussed here. Yet.

I've learned much since writing the above. What I was looking for relates to the MembranePattern? in ObjectCapabilityModel.

And the generation of function calls - I'm not thinking anything fuzzy. Consider a shallow case of F(X,Y,Z) where we require X < Y. We could compile this into two functions, unsafeF(X,Y,Z) that assumes X < Y, and safeF(X,Y,Z) that checks X < Y. By avoiding this extra check and conditional statement, the check can improve performance - more so as the checks grow more complex. Generating the 'unsafeF' and 'safeF' headers is relatively trivial in this case, though it could grow more complicated in the general case - i.e. given ten gated community tests (bounds checks, etc.), we potentially have 2^10 variations on unsafeF functions. The 'trick' is to decide which variations of unsafeF are most worth supporting (worth the extra code size and cache-miss rate, and likely to see repeated use deep in a loop). An optimizer can use a few heuristics and make some good guesses.

I was assuming a CompileTime decision, and use of 'libraries'. That was a long time ago.

Nowadays, my interest lies with LiveProgramming and DistributedProgramming, and more of a 'continuous compilation' approach that will use PartialEvaluation, specializations, inlining, and JustInTimeCompilation to remove unnecessary tests and code paths. I'm somewhat inspired by the work achieved at (luajit.org), though the programming model I pursue (ReactiveDemandProgramming) requires a different set of optimizations.


Note that databases can provide "gates" also. See GateKeeper.
See: BouncerPattern, GatedCommunity

Contributors: TorneWuff, MartySchrader

EditText of this page (last edited July 9, 2010) or FindPage with title or text search