2013-04-28 9 views
5

Hier ist unser einfacher Anwendungsfall: user2 möchte das Dokument von user1 in unser eigenes Repository innerhalb unserer Anwendung kopieren. Sollte einfach sein, oder? Alles, was wir tun müssen, ist, einen zweiten identischen Blob im Blobstore mit dem zurückgegebenen Schlüssel zu erstellen, den wir mit user2 verknüpfen können. Wir müssen hier etwas vermissen. Es scheint, dass die Hauptfunktion des App-Engine-Blob-Speichers darin besteht, Blobs zu handhaben, die von einem Browser hochgeladen und heruntergeladen werden, und eine einfache Kopieroperation, die serverseitig initiiert wird, ist nicht so einfach.Wie erstellt man am besten eine Kopie einer Blobstore-Entität in der App-Engine in Java?

Die offensichtliche Lösung schien die experimentelle Datei api in Java zu verwenden, aber keine Liebe. Es funktioniert, bis Sie in einer Dateigröße von mehr als einem MB oder so aufstehen, dann scheitert es etwas unvorhersehbar. Das alles in die Server-Ebene zu lesen, erscheint auch albern, wenn wir nur eine Kopie in der Speicherschicht machen müssen. Darüber hinaus ist die Wahrscheinlichkeit, dass wir ein experimentelles Feature in unsere Produktionsumgebung bekommen, gering, obwohl es nicht null ist.

Einige Informationen über unsere Umgebung: Die App ist in Java geschrieben und wir verwenden den Blobstore, nicht den Cloud-Speicher und sind für den Moment verpflichtet. Wir sind ein kleines Abteilungs-Team und würden gerne argumentieren, dass die App-Engine eine großartige Plattform ist, aber diese hat uns über den Haufen geworfen. S3 macht das blendend einfach, fehlt uns hier etwas wirklich Dummes?

+1

Da Blobs nicht geändert werden können, warum die Kopie überhaupt machen? Habe einfach einen weiteren Verweis auf den gleichen Blob für user2.Wenn Benutzer den Inhalt des Blobs löschen dürfen, überprüfen Sie den Referenzzähler, bevor Sie ihn wirklich aus dem Blobstore löschen. –

+0

Wir dachten darüber nach, verwarfen aber ziemlich schnell, weil Benutzer löschen können. Angesichts der Eleganz eines einzelnen Blobs und des Schmerzes beim Kopieren ist dies einen anderen Blick wert. Was wäre der beste Weg, dies zu modellieren? Eine Querverweissentität, die verfolgt, ob ein Blob mehr als einen Verweis enthält - einen Eintrag in der Querverweiselemente erstellen, wenn ein Blob "kopiert" wird, und einen Zähler oder eine ID hinzufügen/subtrahieren, bis er "kopiert" oder "gelöscht" wird Es gibt nur eine Referenz. Wir hatten unsere Probleme mit Zählern und dem Datenspeicher, also ist das Löschen, wenn es nur die letzte Referenz ist, etwas gruselig. – coleMan

+0

Nach einiger Debatte haben wir uns entschieden, mit einer Variante von Kalles Vorschlag zu gehen. Beantworten Sie unten, falls es anderen hilft. Auch im Nachhinein dachten wir, wir hätten eine Code-Implementierungsfrage, aber es stellte sich heraus, dass es sich um eine Architekturfrage handelte, die vielleicht besser für den Stack-Austausch von Programmierern geeignet war. – coleMan

Antwort

1

Wir verschrotteten die Idee, eine programmatische Kopie des Blobs mit der Datei api zu machen und mit einer Referenz zu arbeiten, wie Kalle in seinem Kommentar vorgeschlagen hatte, und erstellten eine neue xref-Entität, die Informationen über die Kopie und das Original speichert. Wenn ein Bild oder eine Datei gelöscht wird, überprüfen wir die xfef Entität auf Verweise und löschen diejenigen, die auf das Bild/die Datei zeigen (dh wenn das gelöschte Bild/die Datei von einem anderen kopiert wurde). Wenn wir überhaupt keine Xrefs finden, löschen wir den Blob selbst. Wir haben die Datenschutz-/Compliance-Implikationen nicht gemocht, verwaiste Blobs herumliegen zu lassen, und obwohl die Lagerung billig ist, hilft jedes $$$. Uns gefiel auch die Vorstellung, sozusagen ein sauberes Haus zu haben.

0

Lösung 1: Ich werde eine Google Compute Engine-Instanz starten und den Befehl gsutil verwenden, um die Kopie zu erstellen.

Und dann die Instanz herunterfahren, wenn es fertig ist. Dies ist der schnellste Weg, um die Kopie meines Wissens

gsutil documentation

Lösung 2 zu tun: Aber ich persönlich wählen einen Zähler zu verwenden, wie in den Kommentaren gesagt, weil der Punkt, dass Sie beängstigend Willen sagte ist das gleiche Problem mit der Kopie sein. Verwenden Sie einfach Zähler mit starken Unit-Tests, die zum Beispiel weniger beängstigend sind.

Eine Idee, um es weniger gruselig zu machen ist, wenn Sie 0 für Ihren Zähler erreichen, löschen Sie den Blob nicht sofort, aber machen Sie einen Job, um dies später zu tun. Durch die Verwendung von Scheduled task in Google App Engine. Und löschen Sie die Datei und Ihre tatsächliche Aufzeichnung einen Monat später zum Beispiel.

0

Wie bereits im Kommentar erwähnt, halten Sie einen Blob und übergeben Sie den Schlüssel herum. Aber Sie müssen wirklich nie löschen. Es empfiehlt sich, den Blob für Archivzwecke zu behalten. Also, wie würde delete tatsächlich funktionieren? Verfügen Sie in Ihrem Datenspeichermodell über ein boolesches Löschfeld. Sie entfernen den Blob-Schlüssel beim Löschen nicht aus einer Entität. Stattdessen markieren Sie das boolesche Feld als true. Auf diese Weise hat Ihr Produkt eine Aufzeichnung von jedem Benutzer, der jemals eine Datei besaß. Aber der Benutzer muss es nie wissen.