Showing posts with label whitepaper. Show all posts
Showing posts with label whitepaper. Show all posts

Tuesday, January 8, 2008

An approach to scheduling policies handling and implementation in FreeRTOS

Introduction

The FreeRTOS scheduler is something slightly different from the common concept of "scheduler" people are used to when talking about Operating Systems.
FreeRTOS does indeed provide a scheduling mechanism, not a scheduling policy (C'mon... Round-robin running fixed-priority tasks can't be truly considered a scheduling policy... Can't it?).

1. Possible solutions

Thus the FreeRTOS system lacks a convenient scheduling policy and a convenient way to effortlessly provide it to task developers.
Essentially there are three possible solutions:
  • Hard-coding policies within the FreeRTOS scheduling mechanism
  • Collaborative scheduling
  • Enhanced collaborative scheduling

1.1 Hard-coding policies within the FreeRTOS scheduling mechanism

It essentially means modifying the code which manages context-switches by implementing into this very code the desired scheduling policy.
It is a very comfortable solution, simple and effective, but violates a good software design principle: a neat separation should be kept between mechanisms and policies. Finally, it implies modifying critical portions of the system, potentially introducing very annoying bugs.
These considerations probably make it the worst possible solution among the ones proposed here.

1.2 Collaborative scheduling

Relying on collaborative scheduling (that is: let tasks self-administrate themselves) is another possible choice: tasks share all the same priority and mutually leave the CPU to other ones by calling "taskYELD()". This way tasks are scheduled in a round-robin fashion and each one of them runs for an amount of time decided by the running task itself. This one is kind of an elegant and simple solution, but it lacks in flexibility and, above all, in a real-time environment preemptive scheduling is close to be an unavoidable choice. Least but not last, it often implies each task being aware of the other tasks needs, "intentions" and timings: but such a behavior breaks another very desirable principle: concurrent processes must be kept "isolated".

1.3 Enhanced collaborative scheduling

Probably, the best possible solution is to find a way to build a "Scheduler" task upon the primitives already provided by FreeRTOS, while relying on the preemptive scheduling mechanism it already provides. This approach is the most attractive and elegant one, but it's not simple to think of a way to implement it.

Let's start looking at what primitives and mechanisms FreeRTOS provides.
FreeRTOS has a built-in mechanism for controlling tasks (i.e. them can be suspended, delayed and resumed from an Interrupt Service Request or from an event) and it also provides primitives such as "SetPriority()" and "GetPriority()" for managing the priority of a task.
The fact is we get caught in a sort of deadlock when using these last ones to achieve our objective, as shown from the following example.

Let we have three tasks, aTask, myTask and scheduler. The latter is obviously the scheduler of the system (and it's likely to schedule the other two tasks).

A solution would be to set the highest priority (say "4") for the scheduler and a lower priority for the other tasks (let it be "2"); but by doing so we prevent aTask and myTask by running at all because the scheduling mechanism of FreeRTOS at the moment of the context-switch always chooses the highest priority task.

Well: let's try to play with SetPriority() and GetPriority(): the first time the scheduler gets executed it holds the highest priority; to permit e.g. aTask to run it downgrades its own priority (of the scheduler) and the one of myTask.
But this way, unless aTask calls SetPriority() to boost the scheduler priority before a context-switch occurs, the scheduler and myTask won't have any chance to be executed anymore because of their lower priority.

So a real solution would be to use, instead of the pair Set/GetPriority(), another primitive: taskDELAY() (or, even better, taskDELAY_UNTIL()).
By doing so the algorithm changes as follows: the highest priority task is our scheduler again. When it gets executed it enforces a certain policy (e.g. EDF) by adjusting tasks priorities. Once it has finished its job it just delays its execution of a certain amount of time by calling taskDELAY_UNTIL().
Being the highest priority task, the scheduler it's scheduled immediately once it finishes its delay period (for the sake of precision the scheduler must also wait until a context-switch happens and, because of that, things should be arranged to avoid losing the predictability of the system that assures the hard real-timeness).
During the time the scheduler is sleeping the other, lower-priority, tasks gets executed according to their priority.

Obviously, by using this approach an important effort must be spent in making the amount of processing time used by the scheduler shorter as possible, too.

Although this approach can be considered a particular kind of collaborative scheduling it leaves tasks completely unaware of the policy being applied itself and, best of all, a task isn't required to know nothing nor about other tasks nor about the scheduler (which is, in fact, a task itself).
From a certain point of view, the most attractive feature of this algorithm is the tasks are required to embed no code at all to support it.

Notice how no particular constraints are posed on the policy being chosen, permitting a high degree of freedom to implement in the scheduler whatever we need, without of the tasks becoming aware of that.
This also means this algorithm provides a great flexibility, as explained in the following chapter.

2. Advanced aspects

Three advanced behaviors could be added to our scheme:
  • Dynamic scheduler delay period estimation
  • Multiple-levels schedulers
  • Multiple-policies schedulers

2.1 Dynamic scheduler delay period estimation

With a little effort a powerful feature can be provided to our algorithm: every time the scheduler gets executed it could collect some informations about the tasks and how they are behaving and it may consequently decide different lengths for its delay period to last, resulting in a greatly flexible policy which can try to reserve the highest possible CPU time to the tasks without loosing the advantages of our algorithm.

2.2 Multiple-levels schedulers

Another way of taking advantage of the flexibility of the algorithm is to create a system of multiple schedulers, each one of them acting at a different priority level and managing a group of tasks plus the scheduler of the lower priority level, in a pyramidal partitioning of the tasks.
By performing this partitioning the system could manage e.g. two different groups of tasks, each one of them performing different kind of jobs: one of them could be dedicated to Digital Signal Processing (DSP) and the other could manage all the activities involved in a cell-phone call (which includes DSP operations).

2.3 Multiple-policies schedulers

Multiple-levels schedulers perform a vertical partitioning1 of the scheduling operations, but a "horizontal" partitioning could be adopted as well.

It's the case of a system where more than one scheduler exist, each one of them enforcing a different policy semi-independently from the other schedulers.

Semi-independence is due to the fact that schedulers should avoid as much as possible to reciprocally interfere.

This scheme it's suitable for being used e.g. in a multi-CPU environment when task migration among the CPUs can occur; in such a situation two schedulers can be realised: one of them will manage tasks in a local context and the other one will interact with the other systems of the environment for establishing which task should be migrated and when.


NOTES:
  1. 1 The statement "multiple-levels schedulers perform a vertical partitioning" isn't completely true. In paragraph 2.2 DSP is not "under" other general activities that are performed during a cell-phone call, but is instead part of them. So partitioning should be considered both horizontal and vertical, not only vertical.

Thursday, December 20, 2007

Whitepaper links now working

If you are one of the folks who tried to download my whitepapers, well I'm really sorry for the broken/wrong links you could have found.

The fact is "Altervista.org" (the provider hosting my main site) didn't provide access to non-html files from sites other than those of the Altervista community.
This one turned out to be discovered only today (thanks to Ivan that pointed out the problem!) and I have finished few minutes ago moving files to a newly created ADrive account and making them publicly available (this time for real!).

So, if you want to download them this time it (will/should) work.

My deepest apologizes for the inconvenient.

P.S. If you want to give it a try, Adrive offers 50 Gigabytes of online storage for free. And you know what? When I say "free" I really mean "FREE"...

Wednesday, December 19, 2007

Man at work

Volevasi informare la gentile clientela che il sottoscritto sta lavorando a un whitepaper di piuttosto vasto respiro.
Titolo provvisorio: "Architetture Software: Best practices & Blueprints".

Lo so che come titolo fa un pò schifo, ma consolatevi con quello chè è attualmente lo schema degli argomenti (senza contare che ve l'ho detto che è provvisorio...):
1 "The importance of being Consistent"
1.1 Considerazioni e consigli generali
2. Linee guida per la creazione di nuovi sistemi
2.1 Semplicità
2.2 Omogeneità
2.3 "Separation of Concerns"
3. Architetture stratificate
3.1 Principi e vantaggi
3.2 Sfruttare le librerie sottostanti
3.3 Stratificare il "valore aggiunto"
3.4 Fornire un facile accesso agli strati superiori
4. Consigli di progettazione per librerie software
4.1 Separazione del codice di utilità in librerie per poter essere riutilizzato
4.2 Realizzare API "autonome" e "self-contained" (cioè che per poter essere utilizzate non debbano necessitare di altre librerie esterne)
5. Paradigmi di sviluppo REALMENTE utili
5.1 "Lightweight" Continuous-Integration
5.2 Unit-testing
6. Test
7. Documentazione del codice


Nel caso non fosse chiaro dal precedente elenco mi occuperò di progettazione (pratica) di architetture software, a partire dal basso (ad esempio come progettare una piccola libreria), fino a toccare anche le architetture enterprise (architetture distribuite, SOA, architetture embedded and so on).

Come già detto sono ancora alla fase di raccolta delle idee, ma sin da ora gradirei avere le vostre richieste: "Nicola mettimi un capitolo sull'AOP (Aspected Oriented Programming)", "Nicola che ne dici di parlare di Concurrent Programming", "Nicola e se illustrassi un caso d'uso reale del principio Separation of Concerns?!?", etc. etc.

Nel caso non disponeste di richieste da sottoporre potreste sempre ripiegare su altri tipi di suggerimenti e/o correzioni (bene accette, anche se a seconda di come mi sveglio la mattina).

Monday, December 17, 2007

PDF Whitepaper: "TMIG: Task MIGration library for a multi-CPU, FreeRTOS-based environment"

A new whitepaper made to the light in these cold, rainy days here in Cagliari.

It illustrates design, usage and internals of a C library I'm working on from some months. The "TMIG" library is intended for embedded, multi-CPU environments, based on the FreeRTOS operating system.
I implemented it on a Xilinx Virtex II Pro FPGA, programmed with a 3-CPUs architecture.
CPUs are three Xilinx Microblazes and the memory architecture comprises one private memory for each CPU and a large shared DDR.

I'm considering the possibility of releasing the code in a not so far future (maybe the third quarter of the 2008). If it get released a dual-license style may be chosen (GPLv2/CC/Apache + Commercial).

The TMIG project is part of the Embedded Software Lab, an on-going effort of the Computer Science Department of the University Of Cagliari.


More about the TMIG library and other FreeRTOS-related projects coming soon.
The whitepaper itself is released with the traditional CreativeCommons BY-NC-SA 3.0 license.

Sunday, November 4, 2007

PDF whitepaper: "Tecniche di 'boxing' e 'schermatura' per basi di dati SQL Server 2005"

Il PDF di questo whitepaper è disponibile a questo indirizzo.

Man at work

Qualcuno avrà forse notato che sto sperimentando il formato "whitepaper" applicato al blog.
Si tratta di un esperimento con il quale intendo inaugurare una serie di whitepapers dedicati a casi di studio su progetti reali dei quali mi occupo.

Di questi whitepapers arriveranno al più presto anche le versioni PDF. Giusto il tempo di elaborare un'impaginazione carina.

Tecniche di "boxing" e "schermatura" per basi di dati SQL Server 2005

Nicola Orritos

Abstract

In contesti aziendali complessi ci si trova spesso di fronte a situazioni nelle quali i contenuti di una sola base di dati diventano una risorsa centrale e vitale per buona parte dell'infrastruttura IT dell'intero sistema (sia esso una grossa compagnia o un'organizzazione governativa).
Tale base di dati diventa un hub al quale devono poter accedere un gran numero di sistemi informativi implementati nelle più disparate tecnologie.

Inoltre queste stesse situazioni richiedono sempre più spesso che l'accesso a quegli stessi dati possa essere continuo e il più possibile performante (essendo presenti nell'infrastruttura alcuni sotto-sistemi che eseguono elaborazioni in real-time su di essi).
Una simile mole di richieste deve poter essere accuratamente gestita e controllata, onde evitare dispersioni dei dati, inconsistenze e utilizzi impropri degli stessi. Si ha cioè bisogno di uno strato di intermediazione tra le informazioni contenute nei database e chiunque ne faccia richiesta per qualsiasi motivo.

Questo documento intende esporre alcune delle possibili soluzioni che è possibile adottare per raggiungere tale scopo.
L'esposizione partirà da un'analisi dei vincoli imposti dal dover soddisfare tanti sistemi diversi e prenderà in considerazione un caso particolare nel quale alcune tecnologie pre-esistenti hanno posto dei seri vincoli al'operazione di ristrutturazione intrapresa.

1. La situazione di partenza

Il sistema sul quale si interverrà presenta una classica architettura "client-server", con un'unica base di dati che serve più agenti esterni, ciascuno dei quali ha la necessità di accedere a uno o più insiemi di dati, tutti ugualmente contenuti all'interno di un'unica istanza di un DBMS SqlServer 2005. Gli agenti esterni sono alcuni sistemi informativi appartenenti all'infrastruttura IT di un'unica azienda. Alcuni di loro sono realizzati con tecnologie "compatibili" con la base di dati, altri presentano invece dei problemi di compatibilità che hanno ristretto il numero delle soluzioni applicabili (i vincoli rappresentati da queste incompatibilità saranno analizzati nel paragrafo n.3 , "Requisiti e vincoli").

I dati contenuti nella base di dati (da ora indicata con l'acronimo "DB") devono essere costantemente disponibili ai molti agenti esterni e sarebbe desiderabile se gli accessi potessero avvenire con una certa velocità.
Queste necessità portano però con loro alcune conseguenze potenzialmente molto dannose: spesso e volentieri infatti si tende a varcare il confine che separa un accesso ubiquo ai dati da un loro utilizzo indiscriminato.
Tutto questo quando invece occorrerebbe mantenere i meccanismi e le politiche di accesso i più "semplici" ed efficienti possibili, schermando allo stesso tempo il DB da comportamenti dannosi quali possono essere la proliferazione indiscriminata di utenti, tabelle, viste e permessi.

Inoltre il problema sta non solo nei dati, ma investe anche gli schemi della base di dati e altri aspetti della struttura stessa dei dati: nel caso particolare qui analizzato, prima che ci si rendesse conto delle potenziali ricadute negative della cosa, molti cosiddetti "power-users" ritenuti meritevoli di un accesso poco limitato al sistema hanno dato vita a un variegato insieme di nuove tabelle, viste, Stored Procedure e utenti che costringevano la macchina ospitante il DB a un carico di lavoro a dir poco allarmante.

Un'ulteriore aggravante è costituita dal fatto che queste problematiche hanno un potenziale dannoso che tende a non poter essere controllato con sistemi tradizionali quali l'utilizzo degli "schema" e altre tipologie "classiche" di restrizione dei permessi.
Questo è in parte anche causato dal fatto che SQL Server 2005 utilizza un modello di sicurezza e di controllo degli accessi a dir poco complicato; ben più complicato di quanto potrebbe e dovrebbe essere per poter essere gestito agevolmente da un solo DBA.

2. Requisiti e vincoli

I vincoli ai quali dovrà sottostare la soluzione in grado di ovviare a tutti questi problemi sono molteplici e quasi tutti derivano dall'elevata mole di sistemi che accedono ai dati e dalle diverse modalità con cui ciascuno di essi lo fa.
Innanzitutto dovrà essere garantita un'implementazione semplice: saranno pertanto da evitare approcci che richiedono un eccessivo numero di passaggi da svolgere da parte dei sistemi esterni al DB centrale, così come architetture particolarmente cervellotiche o composte da troppi sistemi che debbano coordinarsi tra loro.

Una cosa importantissima è garantire l'univocità e la consistenza dei dati: nessuna replicazione o distribuzione degli stessi su più DB, a meno che la cosa non possa essere resa trasparente sia a livello di API esposte sia a livello "transazionale" (nel senso relazionale del "termine").

Un altro requisito fondamentale è poi cercare di rendere il passaggio dall'attuale situazione alla nuova il più "indolore" possibile per i sistemi coinvolti: questo significa mantenere il più possibile inalterate le modalità con cui ogni sistema accede al DB; a titolo esemplificativo valga la considerazione che se un sistema accede attualmente tramite una query T-SQLruntime SQL Server, sarebbe auspicabile che non debba in futuro adattarsi ad accedere tramite Web-Service, librerie dati o altre tecnologie diverse da quella già utilizzata.
Ciò è specialmente vero per quegli agenti esterni che basano il loro accesso su una particolare strategia tecnologica in quanto l'unica applicabile per interfacciarsi a SQL Server.

Nel caso reale seguito tutto ciò va a essere ulteriormente complicato dal fatto che dovrà essere garantito ad ogni costo l'uptime del DB, sia dalla soluzione stessa una volta che ne sia stato completato il deployment, sia durante tutta la fase di transizione ad essa.

Infine, il tutto dovrà essere realizzato parallelamente a un altro importantissimo progetto. Si tratta di un'architettura fisica che assicuri al DB centrale alcuni requisiti fondamentali che attualmente non sono ancora stati implementati, in particolare un failovering piuttosto robusto affidato a un cluster di più server (operazione attualmente già oggetto di un ulteriore studio che potrebbe anch'esso essere pubblicato).


3. Premesse a un'efficace soluzione del problema

Sia ben chiaro fin d'ora che non è possibile adempiere a quanto finora esposto senza una intensa collaborazione da parte di tutti i sistemi che accedono e sfruttano la base di dati centrale.
È cioè bene affermare sin da subito che un sistema che voglia accedere ai dati una volta che essi saranno "migrati" alla nuova soluzione non potrà limitarsi a semplici modifiche di alcune delle sue query.
La collaborazione non è infatti richiesta solo a ciascuno di questi sistemi in se, ma anche e soprattutto a coloro i quali di essi fanno utilizzo: saranno queste persone a dover fornire dettagliate descrizioni dei dati ai quali solitamente accedono (o vorrebbero accedere), dei legami tra i dati che intendono estrapolare dai DB, dei formati che si aspettano di ricevere dalle loro query e di tutti quei particolari che saranno poi necessari a fornire a tutti l'accesso più veloce e completo possibile.

Tali sistemi e le persone che ne gestiscono l'accesso al DB centrale saranno cioè parte integrante della soluzione; anzi, a voler essere più precisi, essi e la loro collaborazione saranno la fetta più consistente di essa.

Parte della documentazione che si intende ricavare da questa collaborazione potrà essere estrapolata dalle query e dai dati che già sono stati implementati sulla base di dati e per alcuni di essi sarà probabilmente sufficiente limitarsi a un simile approccio.
Per gli altri casi sarà invece utile (quando non indispensabile) se si potesse procedere alla compilazione da parte dei responsabili dei sistemi coinvolti nell'operazione di una sorta di "questionari" per l'identificazione dei requisiti che si credono necessari per un proficuo utilizzo del DB da parte del software di loro competenza.
Ancor meglio sarebbe organizzare una serie di briefing che possano adempiere a tale compito.


4. Descrizione di alcune delle soluzioni possibili

4.1 Schema generale della soluzione

L'idea generale che si intende perseguire è quella di effettuare un "boxing" dei dati in una struttura software o fisica (o entrambi), che consentano una "schermatura" dei dati stessi dalle influenze esterne.
Si tratta cioè di realizzare una membrana che faccia da mediatore nello scambi di dati occorrente tra il DB centrale e gli agenti esterni che adesso accedono.
Una simile membrana dovrà essere abbastanza intelligente e flessibile da consentire un accesso personalizzato per ogni agente esterno, cercando quanto più possibile di slegarsi dalla tecnologia con cui quest'ultimo si interfaccerà ai dati.
Volendo utilizzare un termine univoco e consistente per riferirsi a questa membrana si farà d'ora in poi uso del sostantivo "Sandbox".

Nonostante le soluzioni presentate differiscano a volte anche pesantemente l'una dall'altra, è possibile individuare tra di esse uno schema comune.
Questo elemento comune è appunto la Sandbox poc'anzi introdotta: un layer di intermediazione tra i dati e l'ecosistema esterno che sarà più o meno visibile alle applicazioni, a seconda dei requisiti di manipolazione dei dati di ciascuna di esse.
Questa "visibilità" discriminatoria ha principalmente la sua ragion d'essere nei requisiti precedentemente elencati: trasparenza e tendenza alla conservazione delle attuali modalità di interfacciamento dei sistemi esterni.

Comunque, quale che sia il modo in cui ciascun sistema esterno "vede" la base di dati, alcuni dei compiti della Sandbox sono stati fissati dal committente del progetto e hanno ovviamente imposto di considerare solo quelle soluzioni che permettevano un'aderenza totale ad essi.
Di seguito l'elenco di questi compiti:
  • supporto all'autenticazione per poter utilizzare i dati
  • logging estensivo delle attività svolte (soprattutto da "chi" esse sono state svolte, quando e in quanto tempo)
  • ottimizzazione spinta delle query eseguite (in modo da non gravare eccessivamente la/e macchina/e ospitante/i il DB)
  • report periodico (a mezzo e-mail) di eventuali malfunzionamenti e di un riassunto delle attività svolte

Un'ultima importantissima funzione integrata nella Sandbox sarà quella di fornire un'interfaccia di programmazione omogenea, ad alto livello e consistente, utilizzabile per creare librerie di accesso personalizzate al DB, secondo i protocolli imposti dalla Sandbox stessa.
Tale interfaccia sarà costituita da API la cui invocazione potrà avvenire sia attraverso script T-SQL sia via codice .NET (C# o VB.NET).

La realizzazione di quest'ultima funzionalità implica a sua volta la creazione di apposite "naming conventions" e di alcune librerie "helper" che aiutino gli utenti dei sistemi esterni a crearsi le proprie routines di accesso ai dati (o ad adattare quelle preesistenti). Tali librerie di supporto saranno parte integrante della Sandbox.

Le convenzioni e gli helpers manterranno essi stessi le modalità di accesso ai dati entro determinati "confini" decisi dagli amministratori del DB centrale.
Confini che dovranno poter essere "spostati" a run-time ricorrendo a un adeguato sistema di configurazione che dovrà perciò essere veloce oltre che omogeneo e di facile comprensione.

In questo strato di API confluirebbe infine tutto lo studio realizzato in collaborazione con i gestori dei vari sistemi esterni, portando cioè a frutto la collaborazione descritta nel paragrafo "3. Premesse a un'efficace soluzione del problema".

(Si noti come alcuni requisiti, ci si riferisce ai punti fissi imposti dal committente, non siano presenti nel paragrafo "2. Requisiti e vincoli" in quanto essi partecipano attivamente e profondamente alla definizione di un particolare schema nella soluzione in via di elaborazione)


4.2 Soluzione n.1: Strato di Web Services

Si tratta della prima e più semplice soluzione che è stata esaminata: semplice, elegante, riutilizzabile e ben supportata sia dalla tecnologia .NET, sia dalle librerie che già sono state scritte (in progetti precedenti) per il DB.

Essa presenta però un serio handicap: costringerebbe chi attualmente accede ai dati tramite query sottoposte direttamente al DB a riscrivere completamente la propria strategia di interfacciamento. Inoltre non tutti i linguaggi e le tecnologie hanno un supporto completo ed efficace agli WebServices.

Si notino comunque due cose che questa soluzione è in parte già stata implementata in almeno un caso particolare: infatti attualmente viene già garantito l'interfacciamento tramite Web Services tra il DB centrale e almeno altri due sistemi dell'ecosistema IT aziendale.
Una seconda nota va poi spesa per affermare come realizzare una soluzione mista (che comprenda quindi anche la tecnologia degli Web Services) sarebbe anch'essa una possibilità sulla quale val la pena contare (a questo proposito si veda il paragrafo "4.6 Pro e contro di un approccio misto").


4.3 Soluzione n.2: Stored Procedures in codice .NET

Piccola premessa: è stata dimostrato anche nel corso di passate collaborazioni con lo stesso committente che scrivere Stored Procedures per il DBMS SQL Server 2005 utilizzando la piattaforma .NET (e il linguaggio C# in particolare) è sufficientemente performante e "sicuro" (pur se non semplicissimo).

Partendo da questo presupposto è naturale ipotizzare uno scenario nel quale l'interfacciamento al DB centrale avvenga continuando ad accedere direttamente al DB, ma non andando più a operare sulle tabelle, bensì su Stored Procedures che ne astraggano dati e semantica, preferibilmente a un livello più alto.
All'atto pratico questo significa che quegli agenti esterni che già utilizzano SQL per accedere ai dati possono continuare a farlo in relativa tranquillità.

Un simile intervento dovrebbe contemplare adeguate convenzioni e verrebbe completato realizzando un modello di programmazione T-SQL e .NET per chi volesse realizzare nuove Stored Procedures: questo adempierebbe perfettamente a quanto descritto nella seconda metà del paragrafo "4.1 Schema generale della soluzione".

La realizzazione di questo modello implica la creazione di un tutorial indipendente dalla tecnologia (perché basato sul linguaggio SQL) e di appositi files di progetto, mirati invece per un utilizzo tramite Visual Studio .NET.
Il tutto guiderebbe all'estensione delle Stored Procedures di base, che saranno comunque già fornite dall'implementazione della soluzione stessa.

Come già detto, quest'approccio garantirebbe il mantenimento della modalità di accesso "diretta" al DB che già molti sistemi adottano: chi già accede in questo modo al DB si potrebbe infatti semplicemente limitare ad aggiornare le proprie query affinché puntino alle opportune Stored Procedures, piuttosto che alle tabelle (alle quali verrebbe tra l'altro precluso l'accesso, di fatto "schermando" l'universo tabellare dagli accessi esterni attraverso lo strato di Stored Procedures).

Inoltre scrivere le Stored Procedures in codice .NET significa che esse potranno svolgere compiti molto più evoluti di quelli permessi dal solo T-SQL: controllo degli accessi e logging fra tutti (adempiendo così ai requisiti elencati nei paragrafi precedenti).

Quasi superfluo aggiungere che combinare questa soluzione con quella che fa uso di Web Services è, oltre che possibile, anche una buona politica: i sistemi che non potessero realizzare librerie di accesso personalizzate in .NET o altri che avrebbero difficoltà ad utilizzare T-SQL potrebbero dialogare con uno o più Web Service appositi.


4.4 Soluzione n.3: Viste modificabili + Stored Procedures

In realtà quella descritta in questo paragrafo è nient'altro che una possibile estensione della precedente (Soluzione n.2): l'accesso non avverrebbe più tramite Stored Procedures, ma tramite "tabelle fittizie" che schermerebbero quelle reali dalla manipolazione diretta da parte dei sistemi esterni.
Le tabelle fittizie possono essere agevolmente realizzate combinando viste, triggers e Stored Procedures: si verrebbero così a creare delle viste modificabili che, reagirebbero a un tentativo di modifica scatenando un trigger che a sua volta invocherebbe apposite Stored Procedures. Si ricadrebbe insomma nella soluzione precedente, ma presentando agli agenti esterni uno schema dei dati ancora più vicino a quello attualmente da loro utilizzato.

Schema che sarebbe inoltre più "ricco" e completo, essendo le viste in questo senso più potenti e più semplici da capire delle Stored Procedures. Questo è un vantaggio che occorre però bilanciare con una maggiore complessità rispetto a quella del modello implementato dalla Soluzione n.2.
Ed è bene far notare come una maggiore complessità porti con se un maggior numero di errori e maggiori costi di manutenzione.


4.5 Soluzione n.4: Macchine "fantasma" + mirroring

Una strada che finora non è stata ancora considerata è quella di una Sandbox "fisica" (piuttosto che software). Per "Sandbox fisica" si intende dividere fisicamente i dati "puri" dalle informazioni che i sistemi esterni vorrebbero ricavare da essi.
Un'esigenza che nasce dal fatto che, nel contesto aziendale che ha richiesto la realizzazione di questo studio, era purtroppo diventata prassi comune realizzare tabelle per raccogliere e aggregare i dati originali in nuove forme; tabelle il cui proliferare indiscriminato genera inconsistenze, ridondanza, pesantezza nell'elaborazione e numerosi problemi di sicurezza.

Questa soluzione vorrebbe "confinare" queste grosse incongruenze a una macchina che non conserva i dati reali ma solo un loro "mirror" preso dal vero DB principale, il quale resterà invece nascosto (un "fantasma") a qualsiasi modifica.
Apposite Stored Procedures o una semplice procedura di mirroring provvederanno alla sincronizzazione delle sole tabelle presenti nel DB "fantasma" con solo i dati rilevanti della macchina esposta all'esterno.

Certo quest'approccio rappresenta senza dubbio un ulteriore livello di sicurezza, ma in se non risolve le problematiche che questo documento ha evidenziato (prima fra tutte l'eccessiva "libertà" con la quale alcuni agenti esterni possono modificare dati e schemi) e pertanto andrebbe adeguatamente integrato con una o più delle altre soluzioni elencate.


4.6 Pro e contro di un approccio misto

Unire alcune delle soluzioni su-esposte è un approccio sicuramente vincente sotto molti aspetti: risolve tutti i problemi e soddisfa tutti i requisiti, garantendo un'elevata flessibilità.
Allo stesso tempo, però, esso porta con se anche alcuni problemi nuovi e non trascurabili, dei quali la complessità è potenzialmente il più dannoso. Sarebbe pertanto opportuno tenere in considerazione l'aumento della complessità quando eventualmente si valuterà come unire le varie soluzioni.

A titolo di esempio: una soluzione come la n.3 ("Viste modificabili + Stored Procedures") è molto potente ma contempla un'architettura costituita di Viste, Triggers e Stored Procedures; ben si capisce che, rispetto alla soluzione n.2 ("Stored Procedures in codice .NET"), l'aumento della complessità è piuttosto rilevante e pericoloso.
Un pericolo che si può potenzialmente manifestare a diversi livelli: concettuale, prestazionale e in sede di manutenzione del sistema.


Conclusioni

Le soluzioni descritte in questo documento sono un primo passo che detterà il modello da seguire nella costruzione del vero e proprio "contenitore intelligente" per i dati del sistema commissionato. Il modello che si andrà a scegliere dovrà poi essere ulteriormente mediato e adattato a un gran numero di diverse esigenze che molti dei software che accedono al DB hanno: alla fine si avrà quasi certamente uno schema misto che include anche alcuni casi particolari (comunque in numero molto esiguo) e che fornirà si un'architettura di interfacciamento solida e uniforme ma anche (e soprattutto) flessibile e facilmente adattabile.