-
Notifications
You must be signed in to change notification settings - Fork 5
WIP : begin working on gridfs implementation #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
.gitignore
Outdated
| vfs/src/test/resources/gcs-test.json | ||
| vfs/src/test/resources/local.conf | ||
| s3/src/test/resources/local.conf | ||
| .metals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ce genre de fichier dépendant de l'env de dev/préférences développeur ne doit pas se retrouver ici, mais dans le .git/info/exclude, le .gitignore doit rester commun/agnostique de ce genre de chose
build.sbt
Outdated
| }, | ||
| libraryDependencies ++= Seq( | ||
| "org.reactivemongo" %% "reactivemongo" % "0.1x", | ||
| "com.typesafe.play" %% "play-json" % playVer.value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Est-ce qu'on a besoin de cette dépendance ?
build.sbt
Outdated
| "org.reactivemongo" %% "reactivemongo" % "0.1x", | ||
| "com.typesafe.play" %% "play-json" % playVer.value, | ||
| Dependencies.slf4jApi, | ||
| "commons-io" % "commons-io" % "2.4" % Test) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idem
build.sbt
Outdated
| "com.typesafe.play" %% "play-json" % playVer.value, | ||
| Dependencies.slf4jApi, | ||
| "commons-io" % "commons-io" % "2.4" % Test) | ||
| "org.reactivemongo" %% "reactivemongo" % "0.17" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ne correspond pas à une version existante : https://search.maven.org/ ou http://reactivemongo.org/
| settings(Common.settings: _*).settings( | ||
| name := "benji-gridfs", | ||
| libraryDependencies ++= Seq( | ||
| Dependencies.slf4jApi, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
je ne pense pas que c'est nécessaire
|
|
||
| final class GridFSTransport() { | ||
|
|
||
| def apply(uri: String, connectionOptions: MongoConnectionOptions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type de retour ? Pour savoir comment créer il faut savoir ce qu'on veut créer et sur quoi ça dépend
| //c'est l'idée, pour l'instant je tatonne encore sur comment récupérer la db de la connexion pour la passer à GridFS(...) | ||
| MongoConnection.parseURI(uri).map { parsedUri => | ||
| val connection = driver.connection(parsedUri, options = connectionOptions) | ||
| GridFS[BSONSerializationPack.type](conn, "fs") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- prefix en paramètre
- le transport et même derrière storage et
BucketRefetObjectRefdoivent resource la DB au moment des appels/opérations (à partir du nom de DB dans l'URI)
| import reactivemongo.api.gridfs.GridFS | ||
| import reactivemongo.api.{ BSONSerializationPack, MongoConnectionOptions } | ||
| import reactivemongo.api.BSONSerializationPack | ||
| import scala.concurrent.ExecutionContext.Implicits.global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On n'utilise pas le contexte global, sauf pour des tests (et encore)
| val gridfsdb = for { | ||
| mongoUri <- Future.fromTry(MongoConnection.parseURI(uri)) | ||
| con = driver.connection(mongoUri) | ||
| dn <- Future(mongoUri.db.get) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option.get est un code smell/bas practice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pourquoi ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
de la même façon qu'il ne faut pas essayer de sortir d'une Future on ne peut pas ignore le contexte optionnelle d'une valeur, il faut travailler avec/dedans (le .get n'aurait jamais dû être exposé dans l'API).
| */ | ||
| final class GridFSFactory extends StorageFactory { | ||
| @SuppressWarnings(Array("org.wartremover.warts.TryPartial")) | ||
| def apply(injector: Injector, uri: URI): ObjectStorage = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, je ne me suis pas encore penché là dessus
| import reactivemongo.api.gridfs.GridFS | ||
| import reactivemongo.api.BSONSerializationPack | ||
| import scala.concurrent.ExecutionContext.Implicits.global | ||
| import scala.concurrent._ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On évite les import en wildcard, qui peuvent cacher des imports dans la scope implicit, par ailleurs il y a une ligne en dessous pour ce package
| case Some(name) => | ||
| con.database(name).map(db => | ||
| GridFS[BSONSerializationPack.type](db, prefix)) | ||
| case None => Future.failed(new RuntimeException(s"Couldn't get the db from $mongoUri")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Si possible utiliser les types d'Exception Benji qui sont dans core
| def apply(uri: String, prefix: String)(implicit ec: ExecutionContext): GridFSTransport = { | ||
| val driver = new reactivemongo.api.MongoDriver | ||
|
|
||
| val gridfsdb = for { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Il ne faut pas assigner une Future issue de .database(..) (résolution de la DB depuis poil):
It’s generally a good practice not to assign the database and collection references to val (even to lazy val), as it’s better to get a fresh reference each time, to automatically recover from any previous issues (e.g. network failure).
http://reactivemongo.org/releases/0.1x/documentation/tutorial/connect-database.html
| import scala.util.{ Failure, Success, Try } | ||
|
|
||
| import com.zengularity.benji.exception.BenjiUnknownError | ||
| import scala.util.Success |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double import
|
|
||
| import reactivemongo.api.gridfs.GridFS | ||
| import reactivemongo.api.BSONSerializationPack | ||
| import scala.concurrent.{ ExecutionContext, Future } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sur la forme, J'essaie de me tenir à un ordre pour les imports, en groupant d'abord les importe JVM/Java classique, après les imports scalalib (import scala...), les imports libs externes (ici reactivemongo), les imports internes/cross pkg (com.zengularity.benji...).
Adaptation des règles javastyle, c'est configurable dans Intellij (Order import)
| def gridfs(prefix: String)(implicit ec: ExecutionContext): Future[GridFS[BSONSerializationPack.type]] = { | ||
| mongoUri.db match { | ||
| case Some(name) => | ||
| for { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for est utile avec plus d'un <- (map), sinon un .map (plus explicite et concis dans ce cas)
| case Some(name) => | ||
| for { | ||
| db <- connection.database(name) | ||
| gridfs = GridFS[BSONSerializationPack.type](db, prefix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quelle différence entre avoir cette ligne et avoir yield GridFS[BSONSerializationPack.type](db, prefix) ?
| } yield gridfs | ||
|
|
||
| case None => | ||
| Future.failed(new BenjiUnknownError(s"Couldn't get the db from $mongoUri")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
La formulation actuelle des erreurs est plutôt "Fails to ..."
| mongoUri <- MongoConnection.parseURI(uri) | ||
| con = driver.connection(mongoUri) | ||
| } yield (mongoUri, con) | ||
| val (mongoUri, connection) = (res.map(_._1), res.map(_._2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pourquoi sortir du for à partir de là ?
| val (mongoUri, connection) = (res.map(_._1), res.map(_._2)) | ||
| connection match { | ||
| case Success(connection) => new Success(GridFSTransport(driver, connection, mongoUri)) | ||
| case Failure(_) => Failure[GridFSTransport](new BenjiUnknownError(s"Couldn't create the connection to $uri")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Le détails de l'erreur/root cause est perdu (cf https://github.com/zengularity/benji/blob/master/core/src/main/scala/exception/BenjiException.scala#L17 )
| package com.zengularity.benji.gridfs | ||
|
|
||
| import com.zengularity.benji.{ Bucket, ObjectStorage } | ||
| import scala.concurrent.ExecutionContext.Implicits.global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oubli ?
| } yield (mongoUri, con) | ||
| val (mongoUri, connection) = (res.map(_._1), res.map(_._2)) | ||
| connection match { | ||
| case Success(connection) => new Success(GridFSTransport(driver, connection, mongoUri)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Success est une case class, pas de new (par ailleurs même pour les class on tend à fournir une factory/apply dans companion pour découpler l'init)
| @@ -0,0 +1,49 @@ | |||
| // /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
| val (mongoUri, connection) = (res.map(_._1), res.map(_._2)) | ||
| connection match { | ||
| case Success(connection) => new Success(GridFSTransport(driver, connection, mongoUri)) | ||
| case Failure(_) => Failure[GridFSTransport](new BenjiUnknownError(s"Couldn't create the connection to $uri")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formulation message "Fails to ..."
| import scala.concurrent.{ ExecutionContext, Future } | ||
| import scala.util.{ Failure, Success, Try } | ||
|
|
||
| import reactivemongo.api.MongoConnection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Il y a un import reactivemongo.api.X plus bas => import reactivemongo.api.{ MongoConnection, X}
| } yield (con, mongoUri) | ||
|
|
||
| res match { | ||
| case Success((connection, mongoUri)) => Success(new GridFSTransport(driver, connection, mongoUri)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pourquoi sortir le case Success du yield précédent (ce qui au passage instancie/alloue un Tuple2 intermédiaire, même si ça n'est pas grave, est-ce utile ?)
| res match { | ||
| case Success((connection, mongoUri)) => Success(new GridFSTransport(driver, connection, mongoUri)) | ||
| case Failure(error) => Failure[GridFSTransport](new BenjiUnknownError(s"Fails to create the connection to $uri", Some(error))) | ||
| res.recoverWith { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recoverWith vs recover
|
|
||
| filesAndChunksStats.transform { | ||
| case Success(_) => Success(true) | ||
| case Failure(_) => Success(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Une storage.transport.gridfs(name) ne devrait pas se retrouver ici
Pull Request Checklist
Fixes
Fixes #xxxx
Purpose
What does this PR do?
Background Context
Why did you take this approach?
References
Are there any relevant issues / PRs / mailing lists discussions?