Lecture de fichier gracieuse sans locking

Aperçu du tableau blanc

Les images ci-dessous sont 1000 x 750 px, ~130 kB JPEGs hébergés sur ImageShack.

  • Interne
  • Global

Information additionnelle

Je dois mentionner que chaque utilisateur (des boîtes client) travaillera directement à partir du partage /Foo . En raison de la nature de l’entreprise, les utilisateurs n’auront jamais besoin de voir ou de travailler sur les documents des autres en même temps, de sorte que les conflits de cette nature ne seront jamais un problème. L’access doit être aussi simple que possible pour eux, ce qui implique probablement de mapper un lecteur sur leur sous-répertoire /Foo/username respectif.

De plus, personne d’autre que mes applications (internes et celles sur le serveur) n’utilisera directement le répertoire FTP.


Implémentations possibles

Malheureusement, il ne semble pas que je puisse utiliser des outils standard tels que WinSCP, car une autre logique doit être intimement liée au processus.

Je pense qu’il y a deux manières simples d’accomplir ce qui précède du côté interne.

  1. Méthode un (lente):

    • Parcourez l’arborescence du répertoire /Foo toutes les N minutes.

    • Diff avec l’arbre précédent en utilisant une combinaison de timestamps (peut être falsifié par les outils de copie de fichiers, mais non pertinent dans ce cas) et sommation.

    • Fusionnez les modifications avec le serveur FTP hors site.

  2. Deuxième méthode:

    • Enregistrez-vous pour les notifications de modification de répertoire (par exemple, en utilisant ReadDirectoryChangesW partir de WinAPI ou FileSystemWatcher si vous utilisez .NET).

    • Enregistrer les modifications

    • Fusionnez les modifications avec le serveur FTP hors site toutes les N minutes.

Je vais probablement finir par utiliser quelque chose comme la deuxième méthode en raison de considérations de performance.


Problème

Étant donné que cette synchronisation doit avoir lieu pendant les heures de bureau, le premier problème qui se pose est lors de la phase de téléchargement hors site.

Alors que je transfère un fichier hors site, j’ai effectivement besoin d’empêcher les utilisateurs d’écrire dans le fichier (par exemple, utilisez CreateFile avec FILE_SHARE_READ ou autre) pendant que je le lis. Les débits Internet en amont dans leur bureau sont loin d’être symésortingques par rapport à la taille des fichiers sur lesquels ils travailleront, il est donc tout à fait possible qu’ils reviennent sur le fichier et tentent de le modifier pendant que je le lis encore.


Solution possible

La solution la plus simple au problème ci-dessus serait de créer une copie du ou des fichiers en question ailleurs sur le système de fichiers et de transférer ces “instantanés” sans perturbation.

Les fichiers (certains seront binarys) avec lesquels ces personnes travailleront sont relativement petits, probablement ≤ 20 Mo, donc leur copie (et donc leur locking temporaire) sera presque instantanée. Les chances qu’ils tentent d’écrire dans le fichier au même instant que je le copie devraient être proches de zéro.

Cette solution semble un peu moche, et je suis sûr qu’il existe une meilleure façon de gérer ce type de problème.

Une chose qui vient à l’esprit est quelque chose comme un filtre de système de fichiers qui prend en charge la réplication et la synchronisation au niveau IRP, un peu comme ce que font certains A / V. C’est exagéré pour mon projet, cependant.


Des questions

C’est la première fois que je dois faire face à ce type de problème, alors peut-être que j’y pense trop.

Je m’intéresse aux solutions propres qui ne nécessitent pas de dépasser la complexité de leurs implémentations. J’ai peut-être manqué quelque chose dans WinAPI qui gère ce problème avec élégance?

Je n’ai pas décidé ce que je vais écrire, mais je suis à l’aise avec: C, C ++, C #, D et Perl.

Après les discussions dans les commentaires, ma proposition serait comme suit:

  • Créez une partition sur votre serveur de données, environ 5 Go pour la sécurité.
  • Créez un projet de service Windows en C # pour surveiller votre pilote / emplacement de données.
  • Lorsqu’un fichier a été modifié, créez une copie locale du fichier contenant la même structure de répertoire et le même emplacement sur la nouvelle partition.
  • Créez un autre service qui ferait ce qui suit:
    • Surveiller les utilisations de bande passante
    • Surveiller les créations de fichiers sur la partition temporaire.
    • Transférer plusieurs fichiers à la fois (Utiliser le thread) sur votre serveur FTP, en respectant les utilisations de la bande passante à l’heure actuelle, en diminuant / augmentant les threads de travail en fonction du trafic réseau.
    • Supprimez les fichiers de la partition qui ont été transférés avec succès.

Donc, fondamentalement, vous avez vos lecteurs:

  • C: Installation de Windows
  • D: Partager le stockage
  • X: Partition temporaire

Vous auriez alors les services suivants:

  • LocalMirrorService – Montres D: et copies vers X: avec la structure dir
  • TransferClientService – Déplace les fichiers de X: vers un serveur FTP, supprime de X:
    • Utilisez également des multi-threads pour déplacer des multiples et surveiller la bande passante.

Je parierais que c’est l’idée que vous aviez en tête, mais cela semble être une approche raisonnable tant que vous êtes vraiment bien dans le développement de votre application et que vous pouvez créer un système solide capable de gérer la plupart des problèmes.

Lorsqu’un utilisateur modifie un document dans Microsoft Word par exemple, le fichier change sur le partage et peut être copié dans X: même si l’utilisateur y travaille toujours, dans Windows, il y a une API pour voir si le descripteur de fichier est toujours ouvert par l’utilisateur, si tel est le cas, vous pouvez simplement créer un hook pour regarder le moment où l’utilisateur ferme le document afin que toutes les modifications soient terminées, vous pouvez alors migrer vers le lecteur X: :.

Ceci étant dit, si l’utilisateur travaille sur le document et que le PC se bloque pour une raison quelconque, le descripteur de document / fichier risque de ne pas être publié tant que le document n’est pas ouvert ultérieurement, provoquant ainsi des problèmes.

Pour ceux qui se trouvent dans une situation similaire (je suppose que la personne qui a posé la question a implémenté une solution depuis longtemps), je suggère une implémentation de rsync .

L’ agent de sauvegarde Windows de rsync.net fait ce qui est décrit dans la méthode 1 et peut également être exécuté en tant que service (voir « Utilisation avancée »). Bien que je ne sois pas tout à fait sûr qu’il ait une limitation de bande passante intégrée …

Duplicati est une autre solution (probablement meilleure) qui limite la bande passante. Il sauvegarde également correctement les fichiers actuellement ouverts ou verrouillés. Utilise SharpRSync, une implémentation rsync gérée, pour son backend. Open source aussi, ce qui est toujours un plus!