Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: nomorelogic - Gennaio 01, 2013, 02:43:38 pm

Titolo: una classe che dipende da un binario
Inserito da: nomorelogic - Gennaio 01, 2013, 02:43:38 pm
Da un po' di tempo sto lavorando su un sistema di backup basato su rsync.
Nulla di nuovo, c'è già qualcosa di genere in giro (ad es. per Win c'è DeltaCopy), però quello che piacerebbe a me, è realizzare un sistema client che possa girare sui 3 maggiori OS (linux, windows, mac) con la stessa interfaccia grafica, le stesse funzionalità, il più semplice e se necessario più avanzato possibile (a dire il vero però le cose che un sistema di backup dovrebbe fare sono molte e, visto il tempo che ho, tocca fare un passo alla volta ;) ).
Questo perchè a seconda dell'OS ci sono un sacco di cose da vedere per rendere funzionante il backup (ad esempio il charset per il salvataggio dei nomi dei file) e se tra macchine fisiche e virtuali si hanno diversi OS non sarebbe male poter configurare il tutto con un unico tool (e fatto con lazarus!).
Senza considerare poi la "magia" degli hard link ma questo ora è OT.

Sono quindi riuscito a trovare una buona configurazione di uso di rsync per Linux e Windows ma ho delle necessità:

La "cosa" sarebbe la classe che ho in mente ed il motivo per cui chiedo il vostro parere.

Domanda 1)
In pratica la classe che voglio realizzare sarebbe un wrapper per l'uso di un binario presente nel filesystem dell'OS attraverso TProcess.
Tramite questa classe ogni applicazione che vorrà usarla avrà la possibilità di impostare il proprio backup dei dati.
Secondo voi, ha senso vincolare una classe alla presenza di un binario?

Domanda 2)
Se ha senso il vincolo classe/binario, la prima cosa che mi è venuta in mente, è quella di usare il costruttore Create per verificare la presenza dei binari (tramite uso direttive di compilazione): se non ci sono, si solleva un'eccezione.

Domanda 3)
C'è un modo migliore per fare il tutto?  ???
Titolo: Re:una classe che dipende da un binario
Inserito da: xinyiman - Gennaio 01, 2013, 02:55:56 pm
La mia domanda e' perché' non crei tutto da 0?
Titolo: Re:una classe che dipende da un binario
Inserito da: nomorelogic - Gennaio 01, 2013, 03:13:54 pm
rsync ha un algoritmo veramente particolare per backup differenziali e credo sia il migliore per copie su pc remoti (anche in caso di connessione lenta).
http://it.wikipedia.org/wiki/Rsync (http://it.wikipedia.org/wiki/Rsync)

Senza considerare che esiste da anni, è stabilissimo e lo si trova anche come servizio nei nas che usano gli hard link per fare le shapshot ad una certa data.
Se hai ad esempio la cartella A di 1Gb e la copi con gli hard link in B, hai 2 cartelle da 1Gb ciascuna ma l'occupazione del disco è sempre 1Gb.
Se in B cambi un file pre-esistente di 4Kb hai una occupazione totale di 1Gb + 4Kb per 2 cartelle diverse da 1Gb ciascuna.



Titolo: Re:una classe che dipende da un binario
Inserito da: Stilgar - Gennaio 01, 2013, 03:26:19 pm
Risposta 1: Può avere senso vincolare la classe alla presenza di un applicativo, tanto più che è il suo wrapper di lancio. Ma dipense dal design complessivo dell'applicazione. E da che punto di vista vuoi privilegiare.

Risposta 2: Controllare che cosa con le direttive di compilazione? Vuoi lincare l'eseguibile dentro il tuo? Allora non vincoli nulla alla presenza nel file system, stai "inglobando" un'applicazione. In Java mi vengono in mente un paio di trucchetti per farlo, ma con il linker del gcc, non ho idea su come iniziare. Figurati del risultato finale ;)

In generale.
Allora ti darei un consiglio spicciolo.
Non fare una classe che fa tutto, perderesti il controllo del codice abbastanza velocemente in situazioni particolarmente eterogenee.
Fai un classe che funga da facade, questa la "connetti" alla classe wrapper. Ogni classe wrapper specifica implementa un'interfaccia o estende una classe astratta che da a disposizione i metodi base per operare le cose che ti interessano.
Come operare la connessione si può usare qualche altro pattern, quello che mi viene in mente è il factory method, in questo modo l'applicazione conosce molti meno dettagli del tuo driver.

Sempre per "parlare".
Codice: [Seleziona]
TDriverFactory = class(TObject)
  public
    class function getBackupDriver : IBackUpDriver;
end;

Dentro questa funzione metti tutte le cose che ti interessano per il riconoscimento del sistema operativo.
Codice: [Seleziona]
// Importa dai file inc la funzione getMachineDipendentBackUpDriver.
{$IFDEF WINDOW}
  {$INCLUDE BackUp.Windows.inc}
{$ENDIF}
{$IFDEF LINUX}
  {$INCLUDE BackUp.Linux.inc}
{$ENDIF}
{$IFDEF MAC}
  {$INCLUDE BackUp.MAC.inc}
{$ENDIF}
{$IFDEF NEW-OS-BY-NOMORE}
  {$INCLUDE BackUp.NEW-OS-BY-NOMORE.inc}
{$ENDIF}

class function TDriverFactory.getBackupDriver : IBackUpDriver;
begin
  result := getMachineDipendentBackUpDriver;
end;


Ti fai tutti le classi dentro varie unit, in modo da lasciare "pulito" da millanta IFDEF.
Sai che mi piace il codice il più pulito possibile.
 ;)
Titolo: Re:una classe che dipende da un binario
Inserito da: nomorelogic - Gennaio 01, 2013, 05:35:28 pm
Risposta 2: Controllare che cosa con le direttive di compilazione? Vuoi lincare l'eseguibile dentro il tuo? Allora non vincoli nulla alla presenza nel file system, stai "inglobando" un'applicazione. In Java mi vengono in mente un paio di trucchetti per farlo, ma con il linker del gcc, non ho idea su come iniziare. Figurati del risultato finale ;)

Niente link, con le direttive di compilazione avevo intenzione di controllare la presenza del binario.
Qualcosa tipo:
Codice: [Seleziona]
constructor TMyBackup.Create(AOwner: TComponent);

   function Test_rsync_binary
   begin
      {$IFDEF LINUX}
       ...
      result :=
      {$ENDIF}
      {$IFDEF WINDOW}
       ...
      result :=
      {$ENDIF}

      ...

   end;

begin
   if not Test_rsync_binary then
      raise exception.Create('unable to find rsync binary!');

   inherited Create(AOwner);
end;

Il problema è che per rilasciare i sorgenti:
[windows]
ho il problema di un setup aggiuntivo di cwRsync: stavo quasi pensando di includere cwRsync come file di risorse e, nel momento del Create, scompatto tutto e lo rendo disponibile; certo che così appesantisco un po' i sorgenti ma almeno chi vorrà usare questa classe sotto win avrà tutto pronto all'uso (anche per la distribuzione finale)

[linux]
potrei provare a testare ed eventualmente richiedere presenza del pacchetto rsync

Titolo: Re:una classe che dipende da un binario
Inserito da: nomorelogic - Gennaio 01, 2013, 05:37:13 pm
Allora ti darei un consiglio spicciolo.
Non fare una classe che fa tutto, perderesti il controllo del codice abbastanza velocemente in situazioni particolarmente eterogenee.
Fai un classe che funga da facade, questa la "connetti" alla classe wrapper. Ogni classe wrapper specifica implementa un'interfaccia o estende una classe astratta che da a disposizione i metodi base per operare le cose che ti interessano.
Come operare la connessione si può usare qualche altro pattern, quello che mi viene in mente è il factory method, in questo modo l'applicazione conosce molti meno dettagli del tuo driver.

In effetti così sarebbe più pulito e si darebbe la possibilità di espandere il sistema abbastanza agilmente.
E' che così mi tocca riscrivere un po' di cose :(
Pazienza, tocca farlo per bene :)
Titolo: Re:una classe che dipende da un binario
Inserito da: Stilgar - Gennaio 01, 2013, 10:02:08 pm
Dai che se funziona per benino lo puoi pubblicare ;)
Titolo: Re:una classe che dipende da un binario
Inserito da: nomorelogic - Gennaio 02, 2013, 09:59:07 am
l'idea era quella
speriamo bene