Skip to content
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

WIP : begin working on gridfs implementation #29

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

nicolasdejonghe
Copy link

Pull Request Checklist

  • Have you read through the contributor guidelines?
  • Have you updated the documentation?
  • Have you added tests for any changed functionality?

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?

.gitignore Outdated
vfs/src/test/resources/gcs-test.json
vfs/src/test/resources/local.conf
s3/src/test/resources/local.conf
.metals
Copy link
Collaborator

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 Show resolved Hide resolved
build.sbt Outdated
},
libraryDependencies ++= Seq(
"org.reactivemongo" %% "reactivemongo" % "0.1x",
"com.typesafe.play" %% "play-json" % playVer.value,
Copy link
Collaborator

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)
Copy link
Collaborator

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"
Copy link
Collaborator

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/

@@ -124,6 +124,7 @@ lazy val gridfs = project.in(file("gridfs")).
settings(Common.settings: _*).settings(
name := "benji-gridfs",
libraryDependencies ++= Seq(
Dependencies.slf4jApi,
Copy link
Collaborator

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) {
Copy link
Collaborator

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")
Copy link
Collaborator

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 BucketRef et ObjectRef doivent resource la DB au moment des appels/opérations (à partir du nom de DB dans l'URI)

package com.zengularity.benji.gridfs

import reactivemongo.api.MongoConnection

import reactivemongo.api.gridfs.GridFS
import reactivemongo.api.{ BSONSerializationPack, MongoConnectionOptions }
import reactivemongo.api.BSONSerializationPack
import scala.concurrent.ExecutionContext.Implicits.global
Copy link
Collaborator

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)
Copy link
Collaborator

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pourquoi ?

Copy link
Collaborator

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 = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy paste ?

Copy link
Author

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

@@ -7,7 +7,7 @@ import reactivemongo.api.MongoConnection

import reactivemongo.api.gridfs.GridFS
import reactivemongo.api.BSONSerializationPack
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
Copy link
Collaborator

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"))
Copy link
Collaborator

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 {
Copy link
Collaborator

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 com.zengularity.benji.exception.BenjiUnknownError
import scala.util.Success
Copy link
Collaborator

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 }
Copy link
Collaborator

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 {
Copy link
Collaborator

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)
Copy link
Collaborator

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"))
Copy link
Collaborator

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))
Copy link
Collaborator

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"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

package com.zengularity.benji.gridfs

import com.zengularity.benji.{ Bucket, ObjectStorage }
import scala.concurrent.ExecutionContext.Implicits.global
Copy link
Collaborator

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))
Copy link
Collaborator

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 @@
// /*
Copy link
Collaborator

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"))
Copy link
Collaborator

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 reactivemongo.api.MongoConnection
Copy link
Collaborator

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))
Copy link
Collaborator

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 {
Copy link
Collaborator

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)
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants