monix.execution.Scheduler Scala Examples
The following examples show how to use monix.execution.Scheduler.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Components.scala From gbf-raidfinder with MIT License | 6 votes |
package walfie.gbf.raidfinder.server import akka.actor.ActorSystem import akka.stream.Materializer import com.trueaccord.scalapb.json.JsonFormat import monix.execution.Scheduler import play.api.BuiltInComponents import play.api.http.{ContentTypes, DefaultHttpErrorHandler} import play.api.libs.json.Json import play.api.Mode.Mode import play.api.mvc._ import play.api.routing.Router import play.api.routing.sird._ import play.core.server._ import play.filters.cors.{CORSConfig, CORSFilter} import play.filters.gzip.GzipFilterComponents import scala.concurrent.duration.FiniteDuration import scala.concurrent.Future import walfie.gbf.raidfinder.protocol.{RaidBossesResponse, BinaryProtobuf} import walfie.gbf.raidfinder.RaidFinder import walfie.gbf.raidfinder.server.controller._ import walfie.gbf.raidfinder.server.syntax.ProtocolConverters.RaidBossDomainOps class Components( raidFinder: RaidFinder[BinaryProtobuf], translator: BossNameTranslator, port: Int, mode: Mode, websocketKeepAliveInterval: FiniteDuration, metricsCollector: MetricsCollector ) extends NettyServerComponents with BuiltInComponents with GzipFilterComponents with Controller { override lazy val serverConfig = ServerConfig(port = Some(port), mode = mode) private val corsFilter = new CORSFilter(corsConfig = CORSConfig().withAnyOriginAllowed) override lazy val httpFilters = List(gzipFilter, corsFilter) lazy val websocketController = new WebsocketController( raidFinder, translator, websocketKeepAliveInterval, metricsCollector )(actorSystem, materializer, Scheduler.Implicits.global) // The charset isn't necessary, but without it, Chrome displays Japanese incorrectly // if you try to view the JSON directly. // https://bugs.chromium.org/p/chromium/issues/detail?id=438464 private val ContentTypeJsonWithUtf8 = "application/json; charset=utf-8" lazy val router = Router.from { case GET(p"/") => controllers.Assets.at(path = "/public", "index.html") case GET(p"/api/bosses.json" ? q_s"name=$names") => val bosses = if (names.nonEmpty) { val knownBossesMap = raidFinder.getKnownBosses names.collect(knownBossesMap) } else raidFinder.getKnownBosses.values val responseProtobuf = RaidBossesResponse( raidBosses = bosses.map(_.toProtocol(translator)).toSeq ) val responseJson = JsonFormat.toJsonString(responseProtobuf) Action(Ok(responseJson).as(ContentTypeJsonWithUtf8)) case GET(p"/api/metrics.json") => val activeUsers = metricsCollector.getActiveWebSocketCount() val json = Json.obj("activeUsers" -> activeUsers) Action(Ok(json)) case GET(p"/ws/raids" ? q_o"keepAlive=${ bool(keepAlive) }") => websocketController.raids(keepAlive = keepAlive.getOrElse(false)) case GET(p"/$file*") => controllers.Assets.at(path = "/public", file = file) } override lazy val httpErrorHandler = new ErrorHandler override def serverStopHook = () => Future.successful { actorSystem.terminate() } }
Example 2
Source File: MockHttpServer.scala From cornichon with Apache License 2.0 | 6 votes |
package com.github.agourlay.cornichon.http.server import java.net.NetworkInterface import com.github.agourlay.cornichon.core.CornichonError import monix.eval.Task import monix.execution.Scheduler import org.http4s.HttpRoutes import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.implicits._ import scala.jdk.CollectionConverters._ import scala.concurrent.duration._ import scala.util.Random class MockHttpServer[A](interface: Option[String], port: Option[Range], mockService: HttpRoutes[Task], maxRetries: Int = 5)(useFromAddress: String => Task[A])(implicit scheduler: Scheduler) { private val selectedInterface = interface.getOrElse(bestInterface()) private val randomPortOrder = port.fold(0 :: Nil)(r => Random.shuffle(r.toList)) private val mockRouter = Router("/" -> mockService).orNotFound def useServer(): Task[A] = if (randomPortOrder.isEmpty) Task.raiseError(MockHttpServerError.toException) else startServerTryPorts(randomPortOrder) private def startServerTryPorts(ports: List[Int], retry: Int = 0): Task[A] = startBlazeServer(ports.head).onErrorHandleWith { case _: java.net.BindException if ports.length > 1 => startServerTryPorts(ports.tail, retry) case _: java.net.BindException if retry < maxRetries => val sleepFor = retry + 1 println(s"Could not start server on any port. Retrying in $sleepFor seconds...") startServerTryPorts(randomPortOrder, retry = retry + 1).delayExecution(sleepFor.seconds) } private def startBlazeServer(port: Int): Task[A] = BlazeServerBuilder[Task](executionContext = scheduler) .bindHttp(port, selectedInterface) .withoutBanner .withHttpApp(mockRouter) .withNio2(true) .resource .use(server => useFromAddress(s"http://${server.address.getHostString}:${server.address.getPort}")) private def bestInterface(): String = NetworkInterface.getNetworkInterfaces.asScala .filter(_.isUp) .flatMap(_.getInetAddresses.asScala) .find(_.isSiteLocalAddress) .map(_.getHostAddress) .getOrElse("localhost") } case object MockHttpServerError extends CornichonError { val baseErrorMessage = "the range of ports provided for the HTTP mock is invalid" }
Example 3
Source File: TwitterStreamer.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder import monix.execution.Scheduler import monix.reactive._ import monix.reactive.subjects.ConcurrentSubject import twitter4j._ // TODO: Write tests trait TwitterStreamer { def observable: Observable[Status] } object TwitterStreamer { val DefaultFilterTerms = Seq("参加者募集!", ":参戦ID", "I need backup!", ":Battle ID") def apply( twitterStream: twitter4j.TwitterStream = TwitterStreamFactory.getSingleton, filterTerms: Seq[String] = DefaultFilterTerms )(implicit scheduler: Scheduler): Twitter4jStreamer = new Twitter4jStreamer(twitterStream, filterTerms) } class Twitter4jStreamer( twitterStream: twitter4j.TwitterStream, filterTerms: Seq[String] )(implicit scheduler: Scheduler) extends TwitterStreamer { private val subject = ConcurrentSubject.publish[Status] val observable: Observable[Status] = subject private val listener = new StatusAdapter() { override def onStatus(status: Status): Unit = subject.onNext(status) override def onException(e: Exception): Unit = println(e) // TODO: Better error handling } twitterStream.addListener(listener) twitterStream.filter(new FilterQuery(filterTerms: _*)) }
Example 4
Source File: BlockingIO.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder.util import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.{Executors, ThreadFactory} import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future, Promise, blocking} import scala.util.control.NonFatal import monix.execution.Scheduler // https://github.com/alexandru/scala-best-practices/blob/master/sections/4-concurrency-parallelism.md object BlockingIO { private val ioThreadPool = Scheduler.io(name = "io-thread") def future[T](t: => T): Future[T] = { val p = Promise[T]() val runnable = new Runnable { def run() = try { p.success(blocking(t)) } catch { case NonFatal(ex) => p.failure(ex) } } ioThreadPool.execute(runnable) p.future } }
Example 5
Source File: ObservablesPartitioner.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder.util import akka.agent.Agent import monix.execution.{Ack, Cancelable, Scheduler} import monix.reactive._ import monix.reactive.observables.GroupedObservable import monix.reactive.observers.Subscriber import monix.reactive.subjects.PublishSubject import scala.concurrent.{ExecutionContext, Future} trait ObservablesPartitioner[K, V] { def getObservable(key: K): Observable[V] } object CachedObservablesPartitioner { def fromUngroupedObservable[K, InputV, OutputV]( observable: Observable[InputV], cacheSizePerKey: Int, keySelector: InputV => K, mappingFunction: InputV => OutputV )(implicit scheduler: Scheduler): (CachedObservablesPartitioner[K, InputV, OutputV], Cancelable) = { val partitioner = new CachedObservablesPartitioner[K, InputV, OutputV](cacheSizePerKey, mappingFunction) val cancelable = observable.groupBy(keySelector).subscribe(partitioner) (partitioner, cancelable) } } class CachedObservablesPartitioner[K, InputV, OutputV]( cacheSizePerKey: Int, mappingFunction: InputV => OutputV )(implicit ec: ExecutionContext) extends Observer[GroupedObservable[K, InputV]] with ObservablesPartitioner[K, OutputV] { private val observablesByKey = Agent[Map[K, Observable[OutputV]]](Map.empty) private val incomingKeys = PublishSubject[K]() def onComplete(): Unit = { incomingKeys.onComplete() } def onError(e: Throwable): Unit = { System.err.println(e) // TODO: Better logging? incomingKeys.onError(e) } def getObservable(key: K): Observable[OutputV] = { observablesByKey.get.getOrElse( key, incomingKeys.findF(_ == key).flatMap(_ => getObservable(key)) ) } }
Example 6
Source File: RaidFinder.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder import java.util.Date import monix.eval.Task import monix.execution.{Cancelable, Scheduler} import monix.reactive._ import scala.concurrent.duration._ import scala.concurrent.Future import twitter4j._ import walfie.gbf.raidfinder.domain._ import walfie.gbf.raidfinder.util.CachedObservablesPartitioner trait RaidFinder[T] { def getRaidTweets(bossName: BossName): Observable[T] def newBossObservable: Observable[RaidBoss] def getKnownBosses(): Map[BossName, RaidBoss] def purgeOldBosses( minDate: Date, levelThreshold: Option[Int] ): Future[Map[BossName, RaidBoss]] def shutdown(): Unit } object RaidFinder { val DefaultCacheSizePerBoss = 20 val DefaultBackfillSize = 200 protected def onShutdown(): Unit = () // TODO: Parsing happens twice somewhere -- should figure out where private val raidInfos = statusesObservable .collect(Function.unlift(StatusParser.parse)) .publish private val (partitioner, partitionerCancelable) = CachedObservablesPartitioner.fromUngroupedObservable( raidInfos.map(_.tweet), cachedTweetsPerBoss, (_: RaidTweet).bossName, fromRaidTweet.from // TODO ) private val (knownBosses, knownBossesCancelable) = KnownBossesObserver .fromRaidInfoObservable(raidInfos, initialBosses) val newBossObservable = knownBosses.newBossObservable private val raidInfosCancelable = raidInfos.connect() private val cancelable = Cancelable { () => List( raidInfosCancelable, partitionerCancelable, knownBossesCancelable ).foreach(_.cancel) onShutdown() } def shutdown(): Unit = cancelable.cancel() def getKnownBosses(): Map[BossName, RaidBoss] = knownBosses.get() def getRaidTweets(bossName: BossName): Observable[T] = partitioner.getObservable(bossName) def purgeOldBosses( minDate: Date, levelThreshold: Option[Int] ): Future[Map[BossName, RaidBoss]] = knownBosses.purgeOldBosses(minDate, levelThreshold) }
Example 7
Source File: WebsocketController.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder.server.controller import akka.actor._ import akka.stream.scaladsl.Flow import akka.stream.{Materializer, OverflowStrategy} import monix.execution.Scheduler import play.api.http.websocket.Message import play.api.libs.streams._ import play.api.mvc._ import play.api.mvc.WebSocket.MessageFlowTransformer import scala.concurrent.duration.FiniteDuration import scala.concurrent.Future import walfie.gbf.raidfinder.domain._ import walfie.gbf.raidfinder.protocol._ import walfie.gbf.raidfinder.RaidFinder import walfie.gbf.raidfinder.server.actor.WebsocketRaidsHandler import walfie.gbf.raidfinder.server.util.MessageFlowTransformerUtil import walfie.gbf.raidfinder.server.{BossNameTranslator, MetricsCollector} class WebsocketController( raidFinder: RaidFinder[BinaryProtobuf], translator: BossNameTranslator, keepAliveInterval: FiniteDuration, metricsCollector: MetricsCollector )(implicit system: ActorSystem, materializer: Materializer, scheduler: Scheduler) extends Controller { private val jsonTransformer = MessageFlowTransformerUtil.protobufJsonMessageFlowTransformer private val binaryTransformer = MessageFlowTransformerUtil.protobufBinaryMessageFlowTransformer private val defaultTransformer = jsonTransformer val flow = ActorFlow.actorRef(props = props) transformer.transform(flow) } case None => Left { val unsupportedProtocols = requestedProtocols.mkString("[", ", ", "]") Results.BadRequest("Unsupported websocket subprotocols " + unsupportedProtocols) } } Future.successful(result) } }
Example 8
Source File: BossNameTranslator.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder.server import akka.agent.Agent import com.pastebin.Pj9d8jt5.ImagePHash import java.awt.image.BufferedImage import java.net.URL import javax.imageio.ImageIO import monix.execution.Scheduler import monix.reactive._ import monix.reactive.subjects.ConcurrentSubject import scala.concurrent.{ExecutionContext, Future} import walfie.gbf.raidfinder.domain._ import walfie.gbf.raidfinder.util.BlockingIO trait BossNameTranslator { import BossNameTranslator.Translation def translate(bossName: BossName): Option[BossName] def update(latestBosses: Map[BossName, RaidBoss]): Future[Unit] def observable(): Observable[Translation] } object BossNameTranslator { case class Translation(from: BossName, to: BossName) } private def croppedImageFromUrl(url: URL): BufferedImage = { // TODO: Use a real HTTP client to get the image val image = ImageIO.read(url.openStream()) image.getSubimage(0, 0, image.getWidth(), image.getHeight() * 3 / 4); } // This assumes there are only two languages (which is true currently) private def findTranslation(newData: TranslationData): Option[BossName] = { translationDataAgent.get.values.find { existingData => newData.hash == existingData.hash && newData.language != existingData.language && newData.level == existingData.level }.map(_.name) } } object ImageBasedBossNameTranslator { case class TranslationData(name: BossName, level: Int, language: Language, hash: ImageHash) case class ImageHash(value: Long) extends AnyVal }
Example 9
package com.wavesplatform.dex.time import java.net.{InetAddress, SocketTimeoutException} import java.util.concurrent.RejectedExecutionException import java.util.concurrent.atomic.AtomicBoolean import com.wavesplatform.dex.domain.utils.ScorexLogging import monix.eval.Task import monix.execution.schedulers.SchedulerService import monix.execution.{ExecutionModel, Scheduler} import org.apache.commons.net.ntp.NTPUDPClient import scala.concurrent.duration.DurationInt class NTP(ntpServer: String) extends Time with ScorexLogging with AutoCloseable { private val offsetPanicThreshold = 1000000L private val ExpirationTimeout = 60.seconds private val RetryDelay = 10.seconds private val ResponseTimeout = 10.seconds private val duringShutdown = new AtomicBoolean(false) private implicit val scheduler: SchedulerService = Scheduler.singleThread( name = "time-impl", daemonic = false, executionModel = ExecutionModel.AlwaysAsyncExecution, reporter = { case _: RejectedExecutionException if duringShutdown.get() => // ignore case e: Throwable => log.error("An uncaught error", e) } ) private val client = new NTPUDPClient() client.setDefaultTimeout(ResponseTimeout.toMillis.toInt) @volatile private var offset = 0L private val updateTask: Task[Unit] = { def newOffsetTask: Task[Option[(InetAddress, java.lang.Long)]] = Task { try { val info = client.getTime(InetAddress.getByName(ntpServer)) info.computeDetails() Option(info.getOffset).map { offset => val r = if (Math.abs(offset) > offsetPanicThreshold) throw new Exception("Offset is suspiciously large") else offset (info.getAddress, r) } } catch { case _: SocketTimeoutException => None case t: Throwable => log.warn("Problems with NTP: ", t) None } } newOffsetTask.flatMap { case None if !scheduler.isShutdown => updateTask.delayExecution(RetryDelay) case Some((server, newOffset)) if !scheduler.isShutdown => log.trace(s"Adjusting time with $newOffset milliseconds, source: ${server.getHostAddress}.") offset = newOffset updateTask.delayExecution(ExpirationTimeout) case _ => Task.unit } } def correctedTime(): Long = System.currentTimeMillis() + offset private var txTime: Long = 0 def getTimestamp(): Long = { txTime = Math.max(correctedTime(), txTime + 1) txTime } private val taskHandle = updateTask.runAsync { case Left(e) => log.error(s"Error executing task", e) case _ => } override def close(): Unit = if (duringShutdown.compareAndSet(false, true)) { log.info("Shutting down Time") taskHandle.cancel() if (client.isOpen) client.close() scheduler.shutdown() } }
Example 10
Source File: DEXExtension.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.grpc.integration import java.net.InetSocketAddress import java.util.concurrent.TimeUnit import com.wavesplatform.dex.grpc.integration.services._ import com.wavesplatform.dex.grpc.integration.settings.DEXExtensionSettings import com.wavesplatform.extensions.{Extension, Context => ExtensionContext} import com.wavesplatform.utils.ScorexLogging import io.grpc.Server import io.grpc.netty.NettyServerBuilder import monix.execution.{ExecutionModel, Scheduler} import net.ceedubs.ficus.Ficus._ import net.ceedubs.ficus.readers.ArbitraryTypeReader._ import net.ceedubs.ficus.readers.NameMapper import scala.concurrent.Future class DEXExtension(context: ExtensionContext) extends Extension with ScorexLogging { @volatile private var server: Server = _ private var apiService: WavesBlockchainApiGrpcService = _ implicit val chosenCase: NameMapper = net.ceedubs.ficus.readers.namemappers.implicits.hyphenCase implicit private val apiScheduler: Scheduler = Scheduler( ec = context.actorSystem.dispatchers.lookup("akka.actor.waves-dex-grpc-scheduler"), executionModel = ExecutionModel.AlwaysAsyncExecution ) override def start(): Unit = { val settings = context.settings.config.as[DEXExtensionSettings]("waves.dex.grpc.integration") val bindAddress = new InetSocketAddress(settings.host, settings.port) apiService = new WavesBlockchainApiGrpcService(context, settings.balanceChangesBatchLinger) server = NettyServerBuilder .forAddress(bindAddress) .permitKeepAliveWithoutCalls(true) .permitKeepAliveTime(500, TimeUnit.MILLISECONDS) .addService(WavesBlockchainApiGrpc.bindService(apiService, apiScheduler)) .build() .start() log.info(s"gRPC DEX extension was bound to $bindAddress") } override def shutdown(): Future[Unit] = { log.info("Shutting down gRPC DEX extension") if (server != null) server.shutdownNow() Future.successful(()) } }
Example 11
Source File: WavesBlockchainCachingClient.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.grpc.integration.clients import java.net.InetAddress import java.time.Duration import com.wavesplatform.dex.domain.account.Address import com.wavesplatform.dex.domain.asset.Asset import com.wavesplatform.dex.domain.bytes.ByteStr import com.wavesplatform.dex.domain.order.Order import com.wavesplatform.dex.domain.transaction.ExchangeTransaction import com.wavesplatform.dex.domain.utils.ScorexLogging import com.wavesplatform.dex.grpc.integration.caches.{AssetDescriptionsCache, FeaturesCache} import com.wavesplatform.dex.grpc.integration.clients.WavesBlockchainClient.SpendableBalanceChanges import com.wavesplatform.dex.grpc.integration.dto.BriefAssetDescription import monix.execution.Scheduler import monix.reactive.Observable import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} class WavesBlockchainCachingClient(underlying: WavesBlockchainClient[Future], defaultCacheExpiration: FiniteDuration, monixScheduler: Scheduler)( implicit grpcExecutionContext: ExecutionContext) extends WavesBlockchainClient[Future] with ScorexLogging { private val cacheExpiration: Duration = Duration.ofMillis(defaultCacheExpiration.toMillis) private val featuresCache = new FeaturesCache(underlying.isFeatureActivated, invalidationPredicate = !_) // we don't keep knowledge about unactivated features private val assetDescriptionsCache = new AssetDescriptionsCache(underlying.assetDescription, cacheExpiration) // TODO remove after release 2.1.3 override def spendableBalance(address: Address, asset: Asset): Future[Long] = underlying.spendableBalance(address, asset) override def spendableBalanceChanges: Observable[SpendableBalanceChanges] = underlying.spendableBalanceChanges override def realTimeBalanceChanges: Observable[WavesBlockchainClient.BalanceChanges] = underlying.realTimeBalanceChanges override def spendableBalances(address: Address, assets: Set[Asset]): Future[Map[Asset, Long]] = underlying.spendableBalances(address, assets) override def allAssetsSpendableBalance(address: Address): Future[Map[Asset, Long]] = underlying.allAssetsSpendableBalance(address) override def isFeatureActivated(id: Short): Future[Boolean] = featuresCache.get(id) map Boolean2boolean override def assetDescription(asset: Asset.IssuedAsset): Future[Option[BriefAssetDescription]] = assetDescriptionsCache.get(asset) override def hasScript(asset: Asset.IssuedAsset): Future[Boolean] = underlying.hasScript(asset) override def runScript(asset: Asset.IssuedAsset, input: ExchangeTransaction): Future[RunScriptResult] = underlying.runScript(asset, input) override def hasScript(address: Address): Future[Boolean] = underlying.hasScript(address) override def runScript(address: Address, input: Order): Future[RunScriptResult] = underlying.runScript(address, input) override def wereForged(txIds: Seq[ByteStr]): Future[Map[ByteStr, Boolean]] = underlying.wereForged(txIds) override def broadcastTx(tx: ExchangeTransaction): Future[Boolean] = underlying.broadcastTx(tx) override def forgedOrder(orderId: ByteStr): Future[Boolean] = underlying.forgedOrder(orderId) override def getNodeAddress: Future[InetAddress] = underlying.getNodeAddress override def close(): Future[Unit] = underlying.close() }
Example 12
Source File: WavesBlockchainClientBuilder.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.grpc.integration import com.wavesplatform.dex.domain.utils.ScorexLogging import com.wavesplatform.dex.grpc.integration.clients.{WavesBlockchainCachingClient, WavesBlockchainClient, WavesBlockchainGrpcAsyncClient} import com.wavesplatform.dex.grpc.integration.settings.WavesBlockchainClientSettings import io.grpc.ManagedChannel import io.grpc.internal.DnsNameResolverProvider import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioSocketChannel import monix.execution.Scheduler import scala.concurrent.{ExecutionContext, Future} object WavesBlockchainClientBuilder extends ScorexLogging { def async(wavesBlockchainClientSettings: WavesBlockchainClientSettings, monixScheduler: Scheduler, grpcExecutionContext: ExecutionContext): WavesBlockchainClient[Future] = { log.info(s"Building gRPC client for server: ${wavesBlockchainClientSettings.grpc.target}") val eventLoopGroup = new NioEventLoopGroup val channel: ManagedChannel = wavesBlockchainClientSettings.grpc.toNettyChannelBuilder .nameResolverFactory(new DnsNameResolverProvider) .executor((command: Runnable) => grpcExecutionContext.execute(command)) .eventLoopGroup(eventLoopGroup) .channelType(classOf[NioSocketChannel]) .usePlaintext() .build new WavesBlockchainCachingClient( new WavesBlockchainGrpcAsyncClient(eventLoopGroup, channel, monixScheduler)(grpcExecutionContext), wavesBlockchainClientSettings.defaultCachesExpiration, monixScheduler )(grpcExecutionContext) } }
Example 13
Source File: ScorexLogging.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.domain.utils import monix.eval.Task import monix.execution.{CancelableFuture, Scheduler} import org.slf4j.{Logger, LoggerFactory} case class LoggerFacade(logger: Logger) { def trace(message: => String): Unit = if (logger.isTraceEnabled) logger.trace(message) def debug(message: => String, arg: Any): Unit = if (logger.isDebugEnabled) logger.debug(message, arg) def debug(message: => String): Unit = if (logger.isDebugEnabled) logger.debug(message) def info(message: => String): Unit = if (logger.isInfoEnabled) logger.info(message) def info(message: => String, arg: Any): Unit = if (logger.isInfoEnabled) logger.info(message, arg) def info(message: => String, throwable: Throwable): Unit = if (logger.isInfoEnabled) logger.info(message, throwable) def warn(message: => String): Unit = if (logger.isWarnEnabled) logger.warn(message) def warn(message: => String, throwable: Throwable): Unit = if (logger.isWarnEnabled) logger.warn(message, throwable) def error(message: => String): Unit = if (logger.isErrorEnabled) logger.error(message) def error(message: => String, throwable: Throwable): Unit = if (logger.isErrorEnabled) logger.error(message, throwable) } trait ScorexLogging { protected lazy val log: LoggerFacade = LoggerFacade(LoggerFactory.getLogger(this.getClass)) implicit class TaskExt[A](t: Task[A]) { def runAsyncLogErr(implicit s: Scheduler): CancelableFuture[A] = logErr.runToFuture(s) def logErr: Task[A] = t.onErrorHandleWith { ex => log.error(s"Error executing task", ex) Task.raiseError[A](ex) } } }
Example 14
Source File: VNodeConstructionBenchmark.scala From outwatch with Apache License 2.0 | 5 votes |
package outwatch import outwatch._ import outwatch.dsl._ import monix.execution.ExecutionModel.SynchronousExecution import monix.execution.schedulers.TrampolineScheduler import monix.execution.Scheduler import outwatch.interpreter.SnabbdomOps import org.scalajs.dom.{ document, window } import scala.scalajs.js import scala.scalajs.js.annotation._ import bench._ object VNodeConstructionBenchmark extends js.JSApp { implicit val scheduler: Scheduler = TrampolineScheduler(Scheduler.global, SynchronousExecution) def main(): Unit = { import scala.concurrent.duration._ bench.util.runComparison(vnodes, List(1), 60.seconds) } val vnodes = Comparison("VNode Construction", Seq( BenchmarkWithoutInit( "10 literal tags", { _ => SnabbdomOps.toSnabbdom(div(span(), a(), img(), hr(), button(), input(), form(), label(), b(), i())) } ), BenchmarkWithoutInit( "10 literal attrs", { size => SnabbdomOps.toSnabbdom(div( id := "a", min := "wo", max := "wa", src := "x", href := "k", target := "j", value := "jo", contentEditable := true, name := "hui", autoComplete := "true" )) } ) )) }
Example 15
Source File: DomLiteralBenchmark.scala From outwatch with Apache License 2.0 | 5 votes |
package outwatch import outwatch._ import outwatch.dsl._ import monix.execution.ExecutionModel.SynchronousExecution import monix.execution.schedulers.TrampolineScheduler import monix.execution.Scheduler import org.scalajs.dom.{ document, window } import scala.scalajs.js import scala.scalajs.js.annotation._ import bench._ object DomLiteralBenchmark extends js.JSApp { def main(): Unit = { import scala.concurrent.duration._ bench.util.runComparison(domLiterals, List(1), 60.seconds) } val domLiterals = Comparison("Dom Literals", Seq( BenchmarkWithoutInit( "10 literal tags", { _ => div(span(), a(), img(), hr(), button(), input(), form(), label(), b(), i()) } ), BenchmarkWithoutInit( "10 literal attrs", { size => div( id := "a", min := "wo", max := "wa", src := "x", href := "k", target := "j", value := "jo", contentEditable := true, name := "hui", autoComplete := "true" ) } ) )) }
Example 16
Source File: OutwatchSpec.scala From outwatch with Apache License 2.0 | 5 votes |
package outwatch import scala.concurrent.Future import cats.effect.ContextShift import cats.effect.IO import monix.execution.Ack.Continue import monix.execution.ExecutionModel.SynchronousExecution import monix.execution.schedulers.TrampolineScheduler import monix.execution.{Cancelable, Scheduler} import monix.reactive.Observable import org.scalajs.dom.{document, window} import org.scalatest.BeforeAndAfterEach import org.scalatest._ import outwatch.Deprecated.IgnoreWarnings.initEvent import org.scalatest.flatspec.{ AnyFlatSpec, AsyncFlatSpec } import org.scalatest.matchers.should.Matchers trait EasySubscribe { implicit class Subscriber[T](obs: Observable[T]) { def apply(next: T => Unit)(implicit s: Scheduler): Cancelable = obs.subscribe { t => next(t) Continue } } } // TODO: We need this mock until localStorage is implemented in jsdom (https://github.com/tmpvar/jsdom/pull/2076) trait LocalStorageMock { import scala.collection.mutable import scala.scalajs.js if (js.isUndefined(window.localStorage)) { val storageObject = new js.Object { private val map = new mutable.HashMap[String, String] def getItem(key: String): String = map.getOrElse(key, null) def setItem(key: String, value: String): Unit = { map += key -> value } def removeItem(key: String): Unit = { map -= key } def clear(): Unit = map.clear() } js.Dynamic.global.window.updateDynamic("localStorage")(storageObject) } def dispatchStorageEvent(key: String, newValue: String, oldValue: String): Unit = { if (key == null) window.localStorage.clear() else window.localStorage.setItem(key, newValue) val event = document.createEvent("Events") initEvent(event)("storage", canBubbleArg = true, cancelableArg = false) event.asInstanceOf[js.Dynamic].key = key event.asInstanceOf[js.Dynamic].newValue = newValue event.asInstanceOf[js.Dynamic].oldValue = oldValue event.asInstanceOf[js.Dynamic].storageArea = window.localStorage window.dispatchEvent(event) () } } trait OutwatchSpec extends Matchers with BeforeAndAfterEach with EasySubscribe with LocalStorageMock { self: Suite => implicit val scheduler: TrampolineScheduler = TrampolineScheduler(Scheduler.global, SynchronousExecution) implicit val cs: ContextShift[IO] = IO.contextShift(scheduler) override def beforeEach(): Unit = { document.body.innerHTML = "" window.localStorage.clear() // prepare body with <div id="app"></div> val root = document.createElement("div") root.id = "app" document.body.appendChild(root) () } } abstract class JSDomSpec extends AnyFlatSpec with OutwatchSpec { implicit def executionContext = scheduler } abstract class JSDomAsyncSpec extends AsyncFlatSpec with OutwatchSpec { override def executionContext = scheduler implicit def ioAssertionToFutureAssertion(io: IO[Assertion]): Future[Assertion] = io.unsafeToFuture() }
Example 17
Source File: Mdl.scala From outwatch-extras with Apache License 2.0 | 5 votes |
package outwatch.extras.mdl import monix.execution.Ack.Continue import monix.execution.Scheduler import org.scalajs.dom import outwatch.Sink import outwatch.dom.VDomModifier import outwatch.dom.dsl.attributes.lifecycle._ import scala.scalajs.js trait Mdl { implicit def scheduler: Scheduler private def componentHandler = js.Dynamic.global.componentHandler private def updateElement(e: dom.Element): Unit = { e.removeAttribute("data-upgraded") if (!js.isUndefined(componentHandler)) componentHandler.upgradeElement(e).asInstanceOf[Unit] } private val insertHook = Sink.create[dom.Element] { e => updateElement(e) Continue } private val postPatchHook = Sink.create[(dom.Element, dom.Element)] { case (_, e) => updateElement(e) Continue } val material: VDomModifier = VDomModifier( insertHook.flatMap(sink => onInsert --> sink), postPatchHook.flatMap(sink => onPostPatch --> sink) ) def material(id: String): VDomModifier = { val update = () => { Option(dom.document.getElementById(id)).foreach(updateElement) Continue } val insertHook = Sink.create[dom.Element](_ => update()) val postPatchHook = Sink.create[(dom.Element, dom.Element)](_ => update() ) VDomModifier( insertHook.flatMap(sink => onInsert --> sink), postPatchHook.flatMap(sink => onPostPatch --> sink) ) } }
Example 18
Source File: DemoStyles.scala From outwatch-extras with Apache License 2.0 | 5 votes |
package demo.styles import monix.execution.Scheduler import outwatch.extras.styles.{ComponentStyle, Styles} import scalacss.DevDefaults._ trait GlobalScheduler { def scheduler = Scheduler.global } trait LogAreaStyle extends ComponentStyle { class Style extends StyleSheet with MdlStyles with GlobalScheduler { import dsl._ val textfield = style( mdl.textfield, height(400.px), width(400.px).important, fontFamily :=! "Courier New", fontSize(14.px).important ) } object Style { implicit object default extends Style with Styles.Publish } } trait TextFieldStyle extends ComponentStyle { class Style extends StyleSheet with MdlStyles with GlobalScheduler { import dsl._ val textfield = style ( mdl.textfield, marginRight(8.px).important ) val textinput = style ( mdl.textinput ) val textlabel = style ( mdl.textlabel ) val button = style ( mdl.button ) } object Style { implicit object default extends Style with Styles.Publish } } trait TodoModuleStyle extends ComponentStyle { class Style extends StyleSheet with MdlStyles with GlobalScheduler { import dsl._ val textinput = style( mdl.textinput ) val textlabel = style( mdl.textlabel ) val button = style( mdl.button, marginLeft(8.px) ) } object Style { implicit object default extends Style with Styles.Publish } }
Example 19
Source File: MonixRestImplicits.scala From udash-core with Apache License 2.0 | 5 votes |
package io.udash package rest.monix import com.avsystem.commons._ import com.avsystem.commons.meta.MacroInstances import com.avsystem.commons.misc.ImplicitNotFound import io.udash.rest.raw.HttpResponseType import io.udash.rest.raw.RawRest.{Async, AsyncEffect} import io.udash.rest.{GenCodecRestImplicits, OpenApiFullInstances, RestOpenApiCompanion} import monix.eval.Task import monix.execution.Scheduler import scala.annotation.implicitNotFound trait MonixRestImplicits extends GenCodecRestImplicits { implicit def scheduler: Scheduler = Scheduler.global implicit def taskToAsync: AsyncEffect[Task] = new AsyncEffect[Task] { def toAsync[A](task: Task[A]): Async[A] = callback => task.runAsync(res => callback(res.fold(Failure(_), Success(_)))) def fromAsync[A](async: Async[A]): Task[A] = Task.async(callback => async(res => callback(res.fold(Left(_), Right(_))))) } @implicitNotFound("${T} is not a valid HTTP method result type - it must be wrapped into a Task") implicit def httpResponseTypeNotFound[T]: ImplicitNotFound[HttpResponseType[T]] = ImplicitNotFound() } object MonixRestImplicits extends MonixRestImplicits abstract class MonixRestApiCompanion[Real]( implicit macroInstances: MacroInstances[MonixRestImplicits, OpenApiFullInstances[Real]] ) extends RestOpenApiCompanion[MonixRestImplicits, Real](MonixRestImplicits)
Example 20
Source File: IOBenchmarks.scala From zio with Apache License 2.0 | 5 votes |
package zio import scala.concurrent.ExecutionContext import cats._ import cats.effect.{ ContextShift, IO => CIO } import cats.effect.{ Fiber => CFiber } import monix.eval.{ Task => MTask } import zio.internal._ object IOBenchmarks extends BootstrapRuntime { override val platform: Platform = Platform.benchmark val TracedRuntime = new BootstrapRuntime { override val platform = Platform.benchmark.withTracing(Tracing.enabled) } import monix.execution.Scheduler implicit val contextShift: ContextShift[CIO] = CIO.contextShift(ExecutionContext.global) implicit val monixScheduler: Scheduler = { import monix.execution.ExecutionModel.SynchronousExecution Scheduler.global.withExecutionModel(SynchronousExecution) } def repeat[R, E, A](n: Int)(zio: ZIO[R, E, A]): ZIO[R, E, A] = if (n <= 1) zio else zio *> repeat(n - 1)(zio) def verify(cond: Boolean)(message: => String): IO[AssertionError, Unit] = ZIO.when(!cond)(IO.fail(new AssertionError(message))) def catsForkAll[A](as: Iterable[CIO[A]]): CIO[CFiber[CIO, List[A]]] = { type Fiber[A] = CFiber[CIO, A] as.foldRight[CIO[CFiber[CIO, List[A]]]](CIO(Applicative[Fiber].pure(Nil))) { (io, listFiber) => Applicative[CIO].map2(listFiber, io.start)((f1, f2) => Applicative[Fiber].map2(f1, f2)((as, a) => a :: as)) } } def catsRepeat[A](n: Int)(io: CIO[A]): CIO[A] = if (n <= 1) io else io.flatMap(_ => catsRepeat(n - 1)(io)) def monixForkAll[A](as: Iterable[MTask[A]]): MTask[CFiber[MTask, List[A]]] = { type Fiber[A] = CFiber[MTask, A] as.foldRight[MTask[CFiber[MTask, List[A]]]](MTask(Applicative[Fiber].pure(Nil))) { (io, listFiber) => MTask.map2(listFiber, io.start)((f1, f2) => Applicative[Fiber].map2(f1, f2)((as, a) => a :: as)) } } def monixRepeat[A](n: Int)(mio: MTask[A]): MTask[A] = if (n <= 1) mio else mio.flatMap(_ => monixRepeat(n - 1)(mio)) class Thunk[A](val unsafeRun: () => A) { def map[B](ab: A => B): Thunk[B] = new Thunk(() => ab(unsafeRun())) def flatMap[B](afb: A => Thunk[B]): Thunk[B] = new Thunk(() => afb(unsafeRun()).unsafeRun()) def attempt: Thunk[Either[Throwable, A]] = new Thunk(() => try Right(unsafeRun()) catch { case t: Throwable => Left(t) } ) } object Thunk { def apply[A](a: => A): Thunk[A] = new Thunk(() => a) def fail[A](t: Throwable): Thunk[A] = new Thunk(() => throw t) } }
Example 21
Source File: Connection.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import monix.execution.Cancelable import monix.execution.CancelableFuture import monix.execution.Scheduler import scribe.Logger import scribe.LoggerSupport final case class Connection( client: LanguageClient, server: CancelableFuture[Unit] ) extends Cancelable { override def cancel(): Unit = server.cancel() } object Connection { def simple(io: InputOutput, name: String)( f: LanguageClient => Services )(implicit s: Scheduler): Connection = Connection( io, Logger(s"$name-server"), Logger(s"$name-client") )(f) def apply( io: InputOutput, serverLogger: LoggerSupport, clientLogger: LoggerSupport )( f: LanguageClient => Services )(implicit s: Scheduler): Connection = { val messages = BaseProtocolMessage.fromInputStream(io.in, serverLogger) val client = LanguageClient.fromOutputStream(io.out, clientLogger) val server = new LanguageServer(messages, client, f(client), s, serverLogger) Connection(client, server.startTask.executeAsync.runAsync) } }
Example 22
Source File: MonixEnrichments.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc import java.io.IOException import java.io.OutputStream import java.nio.ByteBuffer import monix.execution.Ack import monix.execution.Cancelable import monix.execution.Scheduler import monix.reactive.Observable import monix.reactive.Observer import scribe.LoggerSupport object MonixEnrichments { class ObservableCurrentValue[+A](obs: Observable[A])(implicit s: Scheduler) extends (() => A) with Cancelable { private var value: Any = _ private val cancelable = obs.foreach(newValue => value = newValue) override def apply(): A = { if (value == null) { throw new NoSuchElementException( "Reading from empty Observable, consider using MulticastStrategy.behavior(initialValue)" ) } else { value.asInstanceOf[A] } } override def cancel(): Unit = cancelable.cancel() } implicit class XtensionObservable[A](val obs: Observable[A]) extends AnyVal { def focus[B: cats.Eq](f: A => B): Observable[B] = obs.distinctUntilChangedByKey(f).map(f) def toFunction0()(implicit s: Scheduler): () => A = toObservableCurrentValue() def toObservableCurrentValue()( implicit s: Scheduler ): ObservableCurrentValue[A] = new ObservableCurrentValue[A](obs) } implicit class XtensionObserverCompanion[A](val `_`: Observer.type) extends AnyVal { def fromOutputStream( out: OutputStream, logger: LoggerSupport ): Observer.Sync[ByteBuffer] = { new Observer.Sync[ByteBuffer] { private[this] var isClosed: Boolean = false override def onNext(elem: ByteBuffer): Ack = { if (isClosed) Ack.Stop else { try { while (elem.hasRemaining) out.write(elem.get()) out.flush() Ack.Continue } catch { case _: IOException => logger.error("OutputStream closed!") isClosed = true Ack.Stop } } } override def onError(ex: Throwable): Unit = () override def onComplete(): Unit = out.close() } } } }
Example 23
Source File: TestConnection.scala From lsp4s with Apache License 2.0 | 5 votes |
package scala.meta.jsonrpc.testkit import java.io.PipedInputStream import java.io.PipedOutputStream import monix.execution.Cancelable import monix.execution.Scheduler import scala.meta.jsonrpc.Connection import scala.meta.jsonrpc.InputOutput import scala.meta.jsonrpc.LanguageClient import scala.meta.jsonrpc.Services def apply( clientServices: LanguageClient => Services, serverServices: LanguageClient => Services )(implicit s: Scheduler): TestConnection = { val inAlice = new PipedInputStream() val inBob = new PipedInputStream() val outAlice = new PipedOutputStream(inBob) val outBob = new PipedOutputStream(inAlice) val aliceIO = new InputOutput(inAlice, outAlice) val bobIO = new InputOutput(inBob, outBob) val alice = Connection.simple(aliceIO, "alice")(clientServices) val bob = Connection.simple(bobIO, "bob")(serverServices) new TestConnection(alice, aliceIO, bob, bobIO) } }
Example 24
Source File: WatchServiceObservable.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.file.WatchEvent import monix.eval.Task import monix.execution.Ack.{ Continue, Stop } import monix.execution.atomic.Atomic import monix.execution.cancelables.SingleAssignCancelable import monix.execution.exceptions.APIContractViolationException import monix.execution.{ Callback, Cancelable, Scheduler } import monix.reactive.Observable import monix.reactive.observers.Subscriber import scala.concurrent.Future import scala.util.control.NonFatal abstract class WatchServiceObservable extends Observable[Array[WatchEvent[_]]] { def watchService: Option[WatchService] private[this] val wasSubscribed = Atomic(false) override def unsafeSubscribeFn(subscriber: Subscriber[Array[WatchEvent[_]]]): Cancelable = { if (wasSubscribed.getAndSet(true)) { subscriber.onError(APIContractViolationException(this.getClass.getName)) Cancelable.empty } else try startPolling(subscriber) catch { case NonFatal(e) => subscriber.onError(e) Cancelable.empty } } def init(subscriber: Subscriber[Array[WatchEvent[_]]]): Future[Unit] = Future.successful(()) private def startPolling(subscriber: Subscriber[Array[WatchEvent[_]]]): Cancelable = { import subscriber.scheduler val taskCallback = new Callback[Throwable, Array[WatchEvent[_]]]() { override def onSuccess(value: Array[WatchEvent[_]]): Unit = {} override def onError(ex: Throwable): Unit = { subscriber.onError(ex) } } val cancelable = Task .fromFuture(init(subscriber)) .flatMap { _ => loop(subscriber) } .executeWithOptions(_.enableAutoCancelableRunLoops) .runAsync(taskCallback) val extraCancelable = Cancelable(() => { cancelable.cancel() }) SingleAssignCancelable.plusOne(extraCancelable) } private def loop(subscriber: Subscriber[Array[WatchEvent[_]]])(implicit scheduler: Scheduler): Task[Array[WatchEvent[_]]] = { import collection.JavaConverters._ watchService.map { ws => ws.take() .doOnCancel(Task.defer(ws.close())) .flatMap { key => val events = key.pollEvents().asScala.toArray key.reset() Task.fromFuture(subscriber.onNext(events)).flatMap { case Continue => loop(subscriber) case Stop => emptyTask } } } }.getOrElse(emptyTask) private val emptyTask = Task.create[Array[WatchEvent[_]]]((_, _) => Cancelable.empty) }
Example 25
Source File: AsyncSocketChannelClient.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.tcp import monix.eval.Task import monix.execution.Scheduler def close(): Task[Unit] = taskSocketChannel.fold(Task.pure(()))(_.close()) } object AsyncSocketChannelClient { def apply( host: String, port: Int, bufferSize: Int)(implicit scheduler: Scheduler): AsyncSocketChannelClient = { val client = new AsyncSocketChannelClient(host, port, bufferSize) client.init() client } def apply( taskSocketChannel: TaskSocketChannel, bufferSize: Int)(implicit scheduler: Scheduler): AsyncSocketChannelClient = { val client = new AsyncSocketChannelClient(taskSocketChannel, bufferSize) client.init() client } }
Example 26
Source File: AsyncChannelConsumer.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.ByteBuffer import monix.execution.Ack.{ Continue, Stop } import monix.execution.{ Ack, Callback, Cancelable, Scheduler } import monix.execution.atomic.Atomic import monix.execution.cancelables.{ AssignableCancelable, SingleAssignCancelable } import monix.reactive.Consumer import monix.reactive.observers.Subscriber import scala.concurrent.{ Future, Promise } import scala.util.control.NonFatal private[nio] abstract class AsyncChannelConsumer extends Consumer[Array[Byte], Long] { def channel: Option[AsyncChannel] def withInitialPosition: Long = 0L def init(subscriber: AsyncChannelSubscriber): Future[Unit] = Future.successful(()) class AsyncChannelSubscriber(consumerCallback: Callback[Throwable, Long])(implicit val scheduler: Scheduler) extends Subscriber[Array[Byte]] { self => private[this] lazy val initFuture = init(self) private[this] val callbackCalled = Atomic(false) private[this] var position = withInitialPosition override def onNext(elem: Array[Byte]): Future[Ack] = { def write(): Future[Ack] = { val promise = Promise[Ack]() channel.foreach { sc => try { sc .write(ByteBuffer.wrap(elem), position) .runAsync( new Callback[Throwable, Int] { override def onError(exc: Throwable) = { closeChannel() sendError(exc) promise.success(Stop) } override def onSuccess(result: Int): Unit = { position += result promise.success(Continue) } }) } catch { case NonFatal(ex) => sendError(ex) promise.success(Stop) } } promise.future } if (initFuture.value.isEmpty) { initFuture.flatMap(_ => write()) } else { write() } } override def onComplete(): Unit = { channel.collect { case sc if sc.closeOnComplete => closeChannel() } if (callbackCalled.compareAndSet(expect = false, update = true)) consumerCallback.onSuccess(position) } override def onError(ex: Throwable): Unit = { closeChannel() sendError(ex) } private[nio] def onCancel(): Unit = { callbackCalled.set(true) closeChannel() } private[nio] def sendError(t: Throwable) = if (callbackCalled.compareAndSet(expect = false, update = true)) { scheduler.execute(new Runnable { def run() = consumerCallback.onError(t) }) } private[nio] final def closeChannel()(implicit scheduler: Scheduler) = channel.foreach(_.close().runToFuture) } override def createSubscriber(cb: Callback[Throwable, Long], s: Scheduler): (Subscriber[Array[Byte]], AssignableCancelable) = { val out = new AsyncChannelSubscriber(cb)(s) val extraCancelable = Cancelable(() => out.onCancel()) val conn = SingleAssignCancelable.plusOne(extraCancelable) (out, conn) } }
Example 27
Source File: AsyncChannelObservable.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.ByteBuffer import monix.eval.Task import monix.execution.Ack.{ Continue, Stop } import monix.execution.{ Callback, Cancelable, Scheduler } import monix.execution.atomic.Atomic import monix.execution.cancelables.SingleAssignCancelable import monix.execution.exceptions.APIContractViolationException import monix.nio.internal.{ Bytes, EmptyBytes, NonEmptyBytes } import monix.reactive.Observable import monix.reactive.observers.Subscriber import scala.concurrent.Future import scala.util.control.NonFatal private[nio] abstract class AsyncChannelObservable extends Observable[Array[Byte]] { def bufferSize: Int def channel: Option[AsyncChannel] def init(subscriber: Subscriber[Array[Byte]]): Future[Unit] = Future.successful(()) private[this] val wasSubscribed = Atomic(false) override def unsafeSubscribeFn(subscriber: Subscriber[Array[Byte]]): Cancelable = { import subscriber.scheduler if (wasSubscribed.getAndSet(true)) { subscriber.onError(APIContractViolationException(this.getClass.getName)) Cancelable.empty } else try startReading(subscriber) catch { case NonFatal(e) => subscriber.onError(e) closeChannel() Cancelable.empty } } private def startReading(subscriber: Subscriber[Array[Byte]]): Cancelable = { import subscriber.scheduler val taskCallback = new Callback[Throwable, Array[Byte]]() { override def onSuccess(value: Array[Byte]): Unit = { channel.collect { case sc if sc.closeOnComplete => closeChannel() } } override def onError(ex: Throwable): Unit = { closeChannel() subscriber.onError(ex) } } val cancelable = Task .fromFuture(init(subscriber)) .flatMap { _ => loop(subscriber, 0) } .executeWithOptions(_.enableAutoCancelableRunLoops) .runAsync(taskCallback) val extraCancelable = Cancelable(() => { cancelable.cancel() closeChannel() }) SingleAssignCancelable.plusOne(extraCancelable) } private[this] val buffer = ByteBuffer.allocate(bufferSize) private def loop(subscriber: Subscriber[Array[Byte]], position: Long)(implicit scheduler: Scheduler): Task[Array[Byte]] = { buffer.clear() channel.map { ch => ch .read(buffer, position) .doOnCancel(Task.defer(ch.close())) .flatMap { result => val bytes = Bytes(buffer, result) bytes match { case EmptyBytes => subscriber.onComplete() Task.now(Bytes.emptyBytes) case NonEmptyBytes(arr) => Task.fromFuture(subscriber.onNext(arr)).flatMap { case Continue => loop(subscriber, position + result) case Stop => Task.now(Bytes.emptyBytes) } } } }.getOrElse(Task.now(Bytes.emptyBytes)) } private[nio] final def closeChannel()(implicit scheduler: Scheduler) = channel.foreach(_.close().runToFuture) }
Example 28
Source File: ExecutorServiceWrapper.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.internal import java.util import java.util.concurrent.{ AbstractExecutorService, ExecutorService, TimeUnit } import monix.execution.schedulers.{ ReferenceScheduler, SchedulerService } import monix.execution.{ Cancelable, ExecutionModel, Scheduler } import scala.collection.JavaConverters._ import scala.concurrent.duration.Duration import scala.concurrent.{ Await, ExecutionContextExecutorService } private val currentThread: Scheduler = new ReferenceScheduler { import monix.execution.Scheduler.global def execute(r: Runnable): Unit = r.run() def reportFailure(t: Throwable): Unit = throw t def scheduleOnce(initialDelay: Long, unit: TimeUnit, r: Runnable): Cancelable = global.scheduleOnce(initialDelay, unit, r) def executionModel: ExecutionModel = ExecutionModel.Default } }
Example 29
Source File: file.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.ByteBuffer import java.nio.file.WatchEvent.Kind import java.nio.file.{ Path, StandardOpenOption } import monix.execution.Scheduler package object file { def readAsync(path: Path, chunkSize: Int)(implicit s: Scheduler): AsyncFileChannelObservable = { require(chunkSize > 1) val channel = TaskFileChannel(path, StandardOpenOption.READ) new AsyncFileChannelObservable(channel, chunkSize) } def writeAsync( path: Path, flags: Seq[StandardOpenOption] = Seq.empty)(implicit s: Scheduler): AsyncFileChannelConsumer = { appendAsync(path, 0, flags) } def appendAsync( path: Path, startPosition: Long, flags: Seq[StandardOpenOption] = Seq.empty)(implicit s: Scheduler): AsyncFileChannelConsumer = { val flagsWithWriteOptions = flags :+ StandardOpenOption.WRITE :+ StandardOpenOption.CREATE val channel = TaskFileChannel(path, flagsWithWriteOptions: _*) new AsyncFileChannelConsumer(channel, startPosition) } def watchAsync( path: Path, events: Seq[Kind[_]] = Seq.empty)(implicit s: Scheduler): WatchServiceObservable = { val watcher = TaskWatchService(path, events: _*) new AsyncWatchServiceObservable(watcher) } private[file] def asyncChannelWrapper(taskFileChannel: TaskFileChannel) = new AsyncChannel { override val closeOnComplete: Boolean = true override def read(dst: ByteBuffer, position: Long) = taskFileChannel.read(dst, position) override def write(b: ByteBuffer, position: Long) = taskFileChannel.write(b, position) override def close() = taskFileChannel.close() } }
Example 30
Source File: WatchService.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.file import java.nio.file.StandardWatchEventKinds.{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY } import java.nio.file.WatchEvent.Kind import java.nio.file.{ Path, WatchEvent, WatchKey } import com.sun.nio.file.SensitivityWatchEventModifier import monix.execution.{ Callback, Cancelable, Scheduler } import scala.concurrent.{ Future, Promise } import scala.concurrent.duration.TimeUnit import scala.util.control.NonFatal abstract class WatchService extends AutoCloseable { def poll(timeout: Long, timeUnit: TimeUnit, cb: Callback[Throwable, Option[WatchKey]]): Unit def poll(timeout: Long, timeUnit: TimeUnit): Future[Option[WatchKey]] = { val p = Promise[Option[WatchKey]]() poll(timeout, timeUnit, Callback.fromPromise(p)) p.future } def poll(cb: Callback[Throwable, Option[WatchKey]]): Unit def poll(): Future[Option[WatchKey]] = { val p = Promise[Option[WatchKey]]() poll(Callback.fromPromise(p)) p.future } def take(cb: Callback[Throwable, WatchKey]): Unit def take(): Future[WatchKey] = { val p = Promise[WatchKey]() take(Callback.fromPromise(p)) p.future } } object WatchService { val SupportedEvents: Set[Kind[_]] = Set(ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY) def apply(path: Path, events: Kind[_]*)(implicit scheduler: Scheduler): WatchService = { val watcher = path.getFileSystem.newWatchService() val watchFor = if (events.isEmpty) SupportedEvents else events path.register( watcher, watchFor.toArray, SensitivityWatchEventModifier.HIGH.asInstanceOf[WatchEvent.Modifier]) new NIOWatcherServiceImplementation(watcher) } private final class NIOWatcherServiceImplementation(watcher: java.nio.file.WatchService)(implicit scheduler: Scheduler) extends WatchService { override def poll(timeout: Long, timeUnit: TimeUnit, cb: Callback[Throwable, Option[WatchKey]]): Unit = { try { val key = Option(watcher.poll(timeout, timeUnit)) cb.onSuccess(key) } catch { case NonFatal(ex) => cb.onError(ex) } } override def poll(cb: Callback[Throwable, Option[WatchKey]]): Unit = { try { val key = Option(watcher.poll()) cb.onSuccess(key) } catch { case NonFatal(ex) => cb.onError(ex) } } override def take(cb: Callback[Throwable, WatchKey]): Unit = { try { val key = watcher.take() cb.onSuccess(key) } catch { case NonFatal(ex) => cb.onError(ex) } } override def close(): Unit = cancelable.cancel() private[this] val cancelable: Cancelable = Cancelable { () => try watcher.close() catch { case NonFatal(ex) => scheduler.reportFailure(ex) } } } }
Example 31
Source File: TaskWatchService.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.file import java.nio.file.WatchEvent.Kind import java.nio.file.{ Path, WatchKey } import monix.eval.Task import monix.execution.{ Callback, Scheduler } import scala.concurrent.duration.TimeUnit abstract class TaskWatchService { protected val watchService: WatchService def poll(timeout: Long, timeUnit: TimeUnit): Task[Option[WatchKey]] = Task.create { (scheduler, cb) => watchService.poll(timeout, timeUnit, Callback.forked(cb)(scheduler)) } def poll(): Task[Option[WatchKey]] = Task.create { (scheduler, cb) => watchService.poll(Callback.forked(cb)(scheduler)) } def take(): Task[WatchKey] = Task.create { (scheduler, cb) => watchService.take(Callback.forked(cb)(scheduler)) } def close(): Task[Unit] = Task.now(watchService.close()) } object TaskWatchService { def apply(path: Path, events: Kind[_]*)(implicit s: Scheduler): TaskWatchService = { new TaskWatchService { override val watchService: WatchService = WatchService.apply(path, events: _*) } } }
Example 32
Source File: FileChannelForTesting.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.file import java.nio.ByteBuffer import monix.eval.Task import monix.execution.{ Callback, Scheduler } import monix.execution.atomic.Atomic import monix.nio.AsyncChannel class FileChannelForTesting( readingSeq: Vector[Array[Byte]], writeSeq: Atomic[Vector[Array[Byte]]])(implicit s: Scheduler) extends TaskFileChannel with AsyncChannel { private val asyncFileChannelForTesting = new AsyncFileChannelForTesting(readingSeq, writeSeq) override val closeOnComplete: Boolean = true override val asyncFileChannel: AsyncFileChannel = asyncFileChannelForTesting def isClosed = asyncFileChannelForTesting.isClosed def getBytesReadPosition = asyncFileChannelForTesting.getBytesReadPosition def getBytesWritePosition = asyncFileChannelForTesting.getBytesWritePosition def createReadException() = asyncFileChannelForTesting.createReadException() def createWriteException() = asyncFileChannelForTesting.createWriteException() private final class AsyncFileChannelForTesting( readingSeq: Vector[Array[Byte]], writeSeq: Atomic[Vector[Array[Byte]]])(implicit s: Scheduler) extends AsyncFileChannel { private val readChannelPosition = Atomic(0) private val writeChannelPosition = Atomic(0) private val channelClosed = Atomic(false) private val readException = Atomic(false) private val writeException = Atomic(false) def isClosed = channelClosed.get def getBytesReadPosition = readChannelPosition.get def getBytesWritePosition = writeChannelPosition.get def createReadException() = readException.set(true) def createWriteException() = writeException.set(true) def taskCallback(handler: Callback[Throwable, Int]) = new Callback[Throwable, Array[Byte]]() { override def onSuccess(value: Array[Byte]): Unit = handler.onSuccess(value.length) override def onError(ex: Throwable): Unit = handler.onError(ex) } override def isOpen: Boolean = !isClosed override def flush(writeMetaData: Boolean, cb: Callback[Throwable, Unit]): Unit = ??? override def size(cb: Callback[Throwable, Long]): Unit = () //not really used override def read(dst: ByteBuffer, position: Long, handler: Callback[Throwable, Int]) = { if (readException.get) handler.onError(new Exception("Test Exception")) else if (readChannelPosition.get < readingSeq.size) { val pos = readChannelPosition.getAndIncrement() val r = Task { val elem = readingSeq(pos) dst.put(elem) elem } r.runAsync(taskCallback(handler)) } else { handler.onSuccess(-1) } } override def write(b: ByteBuffer, position: Long, handler: Callback[Throwable, Int]) = { if (writeException.get) handler.onError(new Exception("Test Exception")) else { val pos = writeChannelPosition.getAndIncrement() val r = Task { val bytes = b.array() writeSeq.transform { v => if (v.size > pos) v.updated(pos, bytes) else v :+ bytes } bytes } r.runAsync(taskCallback(handler)) } } override def close() = { channelClosed.set(true) } } }
Example 33
Source File: MongoObservableReactivePublisherTest.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package mongo.async import com.avsystem.commons.concurrent.RunNowEC import com.github.ghik.silencer.silent import com.mongodb.async.{client => mongo} import monix.execution.{Cancelable, Scheduler} import org.mockito.ArgumentMatchers.{eq => eqTo, _} import org.mockito.Mockito import org.mockito.Mockito._ import org.mongodb.scala.{Completed, Document, FindObservable, MongoCollection, SingleObservable} import org.scalactic.source.Position import org.scalatest.freespec.AnyFreeSpec import scala.concurrent.duration.Duration @silent("deprecated") class MongoObservableReactivePublisherTest extends AnyFreeSpec { abstract class MockedObservableTests(implicit position: Position) extends MongoObservableExtensions { def subscribe[T](obs: mongo.Observable[T], testSubscriber: TestSubscriber[T]): Unit "should drop test collection" in { val collection = Mockito.mock(classOf[MongoCollection[Document]]) when(collection.drop()).thenReturn(SingleObservable(Completed())) val dropSubscriber = TestSubscriber[Completed]() subscribe(collection.drop(), dropSubscriber) dropSubscriber.assertNoTerminalEvent() dropSubscriber.requestMore(1) dropSubscriber.awaitTerminalEvent(Duration(100, "ms")) dropSubscriber.assertNoErrors() dropSubscriber.assertReceivedOnNext(Seq(Completed())) verify(collection).drop() verifyNoMoreInteractions(collection) } "should insert documents" in { val collection = Mockito.mock(classOf[MongoCollection[Document]]) val insertSubscriber = TestSubscriber[Completed]() when(collection.insertMany(any())).thenReturn(SingleObservable(Completed())) val documents: IndexedSeq[Document] = (1 to 100) map { i: Int => Document("_id" -> i) } subscribe(collection.insertMany(documents), insertSubscriber) insertSubscriber.requestMore(1) insertSubscriber.awaitTerminalEvent(Duration(100, "ms")) insertSubscriber.assertNoErrors() insertSubscriber.assertReceivedOnNext(Seq(Completed())) verify(collection).insertMany(eqTo(documents)) verifyNoMoreInteractions(collection) } "should find documents" in { val documents: IndexedSeq[Document] = (1 to 100) map { i: Int => Document("_id" -> i) } val original = Mockito.mock(classOf[FindObservable[Document]]) val findSubscriber = TestSubscriber[Document]() doNothing().when(original).subscribe(any()) subscribe(original, findSubscriber) findSubscriber.assertNoTerminalEvent() findSubscriber.requestMore(101) documents.foreach(findSubscriber.onNext) findSubscriber.onComplete() findSubscriber.awaitTerminalEvent(Duration(100, "ms")) findSubscriber.assertNoErrors() findSubscriber.assertReceivedOnNext(documents) verify(original).subscribe(any(classOf[mongo.Observer[_ >: Document]])) verifyNoMoreInteractions(original) } } "A Mongo-Reactive observable" - new MockedObservableTests { override def subscribe[T](obs: mongo.Observable[T], testSubscriber: TestSubscriber[T]): Unit = obs.asReactive.subscribe(testSubscriber) } "A Mongo-Monix observable" - new MockedObservableTests { override def subscribe[T](obs: mongo.Observable[T], testSubscriber: TestSubscriber[T]): Unit = obs.asMonix.subscribe( monix.reactive.observers.Subscriber.fromReactiveSubscriber(testSubscriber, Cancelable.empty)(Scheduler(RunNowEC)) ) } }
Example 34
Source File: PathDirectives.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin.directives import java.util.UUID import akka.http.scaladsl.server.Directive1 import akka.http.scaladsl.server.Directives._ import ch.epfl.bluebrain.nexus.admin.index.{OrganizationCache, ProjectCache} import monix.eval.Task import monix.execution.Scheduler import scala.util.Try object PathDirectives { def project(implicit cache: ProjectCache[Task], s: Scheduler): Directive1[(String, String)] = pathPrefix(Segment / Segment).tflatMap { case (orgSegment, projSegment) => Try((UUID.fromString(orgSegment), UUID.fromString(projSegment))) .map { case (orgUuid, projUuid) => onSuccess(cache.get(orgUuid, projUuid).runToFuture).flatMap { case Some(resource) => provide((resource.value.organizationLabel, resource.value.label)) case None => provide((orgSegment, projSegment)) } } .getOrElse(provide((orgSegment, projSegment))) } }
Example 35
Source File: RepairFromMessages.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin import java.util.UUID import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.PersistenceQuery import ch.epfl.bluebrain.nexus.admin.organizations.Organizations import ch.epfl.bluebrain.nexus.admin.projects.Projects import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import scala.concurrent.Future import scala.util.Try object RepairFromMessages { private val log = Logger[RepairFromMessages.type] def repair( o: Organizations[Task], p: Projects[Task] )(implicit as: ActorSystem, sc: Scheduler): Future[Unit] = { val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) pq.currentPersistenceIds() .mapAsync(1) { case OrgId(uuid) => (o.fetch(uuid) >> Task.unit).runToFuture case ProjId(uuid) => (p.fetch(uuid) >> Task.unit).runToFuture case other => log.warn(s"Unknown persistence id '$other'") Future.successful(()) } .runFold(0) { case (acc, _) => if (acc % 100 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .map(_ => ()) } sealed abstract class PersistenceId(prefix: String) { private val len = prefix.length def unapply(arg: String): Option[UUID] = if (arg.startsWith(prefix)) Try(UUID.fromString(arg.drop(len))).toOption else None } object OrgId extends PersistenceId("organizations-") object ProjId extends PersistenceId("projects-") }
Example 36
Source File: ProjectDirectives.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.directives import java.util.UUID import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.{Directive0, Directive1} import cats.implicits._ import ch.epfl.bluebrain.nexus.admin.client.AdminClient import ch.epfl.bluebrain.nexus.admin.client.types.{Organization, Project} import ch.epfl.bluebrain.nexus.iam.client.types.AuthToken import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject import ch.epfl.bluebrain.nexus.kg.KgError.{OrganizationNotFound, ProjectIsDeprecated, ProjectNotFound} import ch.epfl.bluebrain.nexus.kg.cache.ProjectCache import ch.epfl.bluebrain.nexus.kg.config.Schemas import ch.epfl.bluebrain.nexus.kg.resources.{OrganizationRef, ProjectInitializer} import ch.epfl.bluebrain.nexus.kg.resources.ProjectIdentifier._ import ch.epfl.bluebrain.nexus.kg.resources.syntax._ import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.service.config.Vocabulary.nxv import monix.eval.Task import monix.execution.Scheduler import scala.util.{Success, Try} object ProjectDirectives { // TODO: Remove when migrating ADMIN client implicit private val fakeToken: Option[AuthToken] = None val defaultPrefixMapping: Map[String, AbsoluteIri] = Map( "resource" -> Schemas.unconstrainedSchemaUri, "schema" -> Schemas.shaclSchemaUri, "view" -> Schemas.viewSchemaUri, "resolver" -> Schemas.resolverSchemaUri, "file" -> Schemas.fileSchemaUri, "storage" -> Schemas.storageSchemaUri, "nxv" -> nxv.base, "documents" -> nxv.defaultElasticSearchIndex.value, "graph" -> nxv.defaultSparqlIndex.value, "defaultResolver" -> nxv.defaultResolver.value, "defaultStorage" -> nxv.defaultStorage.value ) def projectNotDeprecated(implicit proj: Project): Directive0 = if (proj.deprecated) failWith(ProjectIsDeprecated(proj.projectLabel)) else pass }
Example 37
Source File: RepairFromMessages.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg import java.net.URLDecoder import java.util.UUID import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.PersistenceQuery import ch.epfl.bluebrain.nexus.kg.resources.{Id, Repo, ResId} import ch.epfl.bluebrain.nexus.kg.resources.ProjectIdentifier.ProjectRef import ch.epfl.bluebrain.nexus.rdf.Iri import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import scala.concurrent.Future import scala.util.Try object RepairFromMessages { // $COVERAGE-OFF$ private val log = Logger[RepairFromMessages.type] def repair(repo: Repo[Task])(implicit as: ActorSystem, sc: Scheduler, pm: CanBlock): Unit = { log.info("Repairing dependent tables from messages.") val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) Task .fromFuture { pq.currentPersistenceIds() .mapAsync(1) { case ResourceId(id) => (repo.get(id, None).value >> Task.unit).runToFuture case other => log.warn(s"Unknown persistence id '$other'") Future.successful(()) } .runFold(0) { case (acc, _) => if (acc % 1000 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .map(_ => ()) } .runSyncUnsafe() log.info("Finished repairing dependent tables from messages.") } object ResourceId { private val regex = "^resources\\-([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12})\\-(.+)$".r def unapply(arg: String): Option[ResId] = arg match { case regex(stringUuid, stringId) => for { uuid <- Try(UUID.fromString(stringUuid)).toOption iri <- Iri.absolute(URLDecoder.decode(stringId, "UTF-8")).toOption } yield Id(ProjectRef(uuid), iri) case _ => None } } // $COVERAGE-ON$ }
Example 38
Source File: RepairFromMessages.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam import java.net.URLDecoder import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.PersistenceQuery import ch.epfl.bluebrain.nexus.iam.acls.Acls import ch.epfl.bluebrain.nexus.iam.permissions.Permissions import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.types.Label import ch.epfl.bluebrain.nexus.rdf.Iri.Path import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import scala.concurrent.Future object RepairFromMessages { // $COVERAGE-OFF$ private val log = Logger[RepairFromMessages.type] def repair( p: Permissions[Task], r: Realms[Task], a: Acls[Task] )(implicit as: ActorSystem, sc: Scheduler, pm: CanBlock): Unit = { val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) pq.currentPersistenceIds() .mapAsync(1) { case PermissionsId() => p.agg.currentState(p.persistenceId).runToFuture case RealmId(label) => r.agg.currentState(label.value).runToFuture case AclId(path) => a.agg.currentState(path.asString).runToFuture case other => log.warn(s"Unknown persistence id '$other'") Future.successful(()) } .runFold(0) { case (acc, _) => if (acc % 100 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .runSyncDiscard() log.info("Repair from messages table completed.") } sealed abstract class PersistenceId(prefix: String) { private val len = prefix.length protected def dropPrefix(arg: String): Option[String] = if (arg.startsWith(prefix)) Some(arg.drop(len)) else None } object RealmId extends PersistenceId("realms-") { def unapply(arg: String): Option[Label] = dropPrefix(arg).map(Label.unsafe) } object AclId extends PersistenceId("acls-") { def unapply(arg: String): Option[Path] = dropPrefix(arg).flatMap(str => Path(URLDecoder.decode(str, "UTF-8")).toOption) } object PermissionsId { def unapply(arg: String): Boolean = arg == "permissions-permissions" } implicit class RichFuture[A](val future: Future[A]) extends AnyVal { def runSyncDiscard()(implicit s: Scheduler, permit: CanBlock): Unit = Task.fromFuture(future).map(_ => ()).runSyncUnsafe() } // $COVERAGE-ON$ }
Example 39
Source File: AuthDirectives.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.service.directives import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.directives.Credentials import akka.http.scaladsl.server.directives.FutureDirectives.onComplete import akka.http.scaladsl.server.{Directive0, Directive1} import cats.implicits._ import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError.AuthorizationFailed import ch.epfl.bluebrain.nexus.iam.acls.{AccessControlLists, Acls} import ch.epfl.bluebrain.nexus.iam.auth.AccessToken import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.types.IamError.InvalidAccessToken import ch.epfl.bluebrain.nexus.iam.types.{Caller, Permission} import ch.epfl.bluebrain.nexus.kg.KgError.AuthenticationFailed import ch.epfl.bluebrain.nexus.rdf.Iri.{AbsoluteIri, Path} import ch.epfl.bluebrain.nexus.rdf.Iri.Path._ import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError.InternalError import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import scala.concurrent.Future import scala.util.{Failure, Success} def extractCallerAcls(path: Path)(implicit c: Caller): Directive1[AccessControlLists] = onComplete(acls.list(path, ancestors = true, self = true).runToFuture).flatMap { case Success(AccessControlLists.empty) => failWith(AuthorizationFailed) case Success(result) => provide(result) case Failure(err) => val message = "Error when trying to check for permissions" logger.error(message, err) failWith(InternalError(message)) } }
Example 40
Source File: instances.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.service.marshallers import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller import akka.http.scaladsl.marshalling._ import akka.http.scaladsl.model.MediaTypes.`application/json` import akka.http.scaladsl.model._ import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError import ch.epfl.bluebrain.nexus.admin.organizations.OrganizationRejection import ch.epfl.bluebrain.nexus.admin.projects.ProjectRejection import ch.epfl.bluebrain.nexus.commons.circe.syntax._ import ch.epfl.bluebrain.nexus.commons.http.JsonLdCirceSupport.OrderedKeys import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._ import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom import ch.epfl.bluebrain.nexus.iam.acls.AclRejection import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsRejection import ch.epfl.bluebrain.nexus.iam.realms.RealmRejection import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.orderedKeys import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError.InternalError import ch.epfl.bluebrain.nexus.service.routes.ResourceRejection import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport import io.circe._ import io.circe.syntax._ import monix.eval.Task import monix.execution.Scheduler import scala.collection.immutable.Seq import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration object instances extends FailFastCirceSupport { implicit val finiteDurationEncoder: Encoder[FiniteDuration] = Encoder.encodeString.contramap(fd => s"${fd.toMillis} ms") implicit val resourceRejectionEncoder: Encoder[ResourceRejection] = Encoder.instance { case r: ProjectRejection => Encoder[ProjectRejection].apply(r) case r: OrganizationRejection => Encoder[OrganizationRejection].apply(r) case r: AclRejection => Encoder[AclRejection].apply(r) case r: RealmRejection => Encoder[RealmRejection].apply(r) case r: PermissionsRejection => Encoder[PermissionsRejection].apply(r) case _ => Encoder[ServiceError].apply(InternalError("unspecified")) } implicit val resourceRejectionStatusFrom: StatusFrom[ResourceRejection] = StatusFrom { case r: OrganizationRejection => OrganizationRejection.organizationStatusFrom(r) case r: ProjectRejection => ProjectRejection.projectStatusFrom(r) case r: AclRejection => AclRejection.aclRejectionStatusFrom(r) case r: RealmRejection => RealmRejection.realmRejectionStatusFrom(r) case r: PermissionsRejection => PermissionsRejection.permissionsRejectionStatusFrom(r) } override def unmarshallerContentTypes: Seq[ContentTypeRange] = List(`application/json`, `application/ld+json`, `application/sparql-results+json`) implicit final def rejection[A <: ResourceRejection: Encoder](implicit statusFrom: StatusFrom[A], printer: Printer = Printer.noSpaces.copy(dropNullValues = true), ordered: OrderedKeys = orderedKeys ): ToResponseMarshaller[A] = { val marshallers = Seq(`application/ld+json`, `application/json`).map { contentType => Marshaller.withFixedContentType[A, HttpResponse](contentType) { rejection => HttpResponse( status = statusFrom(rejection), entity = HttpEntity(contentType, printer.print(rejection.asJson.sortKeys)) ) } } Marshaller.oneOf(marshallers: _*) } implicit class EitherTask[R <: ResourceRejection, A](task: Task[Either[R, A]])(implicit s: Scheduler) { def runWithStatus(code: StatusCode): Future[Either[R, (StatusCode, A)]] = task.map(_.map(code -> _)).runToFuture } implicit class OptionTask[A](task: Task[Option[A]])(implicit s: Scheduler) { def runNotFound: Future[A] = task.flatMap { case Some(a) => Task.pure(a) case None => Task.raiseError(AdminError.NotFound) }.runToFuture } }
Example 41
Source File: instances.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.storage.routes import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller import akka.http.scaladsl.marshalling._ import akka.http.scaladsl.model.MediaTypes._ import akka.http.scaladsl.model._ import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._ import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.sortKeys import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.OrderedKeys import ch.epfl.bluebrain.nexus.storage.Rejection import ch.epfl.bluebrain.nexus.storage.config.AppConfig._ import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport import io.circe._ import io.circe.syntax._ import monix.eval.Task import monix.execution.Scheduler import scala.collection.immutable.Seq import scala.concurrent.Future object instances extends LowPriority { implicit final def valueWithStatusCodeMarshaller[A: Encoder](implicit printer: Printer = defaultPrinter, keys: OrderedKeys = orderedKeys ): ToResponseMarshaller[(StatusCode, A)] = jsonLdWithStatusCodeMarshaller.compose { case (status, value) => status -> value.asJson } private[routes] def onOf[A, Response]( fMarshaller: MediaType.WithFixedCharset => Marshaller[A, Response] ): Marshaller[A, Response] = { val marshallers = Seq(`application/ld+json`, `application/json`).map(fMarshaller) Marshaller.oneOf(marshallers: _*) } }
Example 42
Source File: Main.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.storage import java.nio.file.Paths import java.time.Clock import akka.actor.ActorSystem import akka.event.{Logging, LoggingAdapter} import akka.http.scaladsl.Http import akka.http.scaladsl.server.Route import akka.util.Timeout import cats.effect.Effect import ch.epfl.bluebrain.nexus.storage.Storages.DiskStorage import ch.epfl.bluebrain.nexus.storage.attributes.AttributesCache import ch.epfl.bluebrain.nexus.storage.config.{AppConfig, Settings} import ch.epfl.bluebrain.nexus.storage.config.AppConfig._ import ch.epfl.bluebrain.nexus.storage.routes.Routes import com.typesafe.config.{Config, ConfigFactory} import kamon.Kamon import monix.eval.Task import monix.execution.Scheduler import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContext, Future} import scala.util.{Failure, Success} //noinspection TypeAnnotation // $COVERAGE-OFF$ object Main { def loadConfig(): Config = { val cfg = sys.env.get("STORAGE_CONFIG_FILE") orElse sys.props.get("storage.config.file") map { str => val file = Paths.get(str).toAbsolutePath.toFile ConfigFactory.parseFile(file) } getOrElse ConfigFactory.empty() (cfg withFallback ConfigFactory.load()).resolve() } def setupMonitoring(config: Config): Unit = { if (sys.env.getOrElse("KAMON_ENABLED", "false").toBoolean) { Kamon.reconfigure(config) Kamon.loadModules() } } def shutdownMonitoring(): Unit = { if (sys.env.getOrElse("KAMON_ENABLED", "false").toBoolean) { Await.result(Kamon.stopModules(), 10.seconds) } } @SuppressWarnings(Array("UnusedMethodParameter")) def main(args: Array[String]): Unit = { val config = loadConfig() setupMonitoring(config) implicit val appConfig: AppConfig = Settings(config).appConfig implicit val as: ActorSystem = ActorSystem(appConfig.description.fullName, config) implicit val ec: ExecutionContext = as.dispatcher implicit val eff: Effect[Task] = Task.catsEffect(Scheduler.global) implicit val iamIdentities: IamIdentitiesClient[Task] = new IamIdentitiesClient[Task](appConfig.iam) implicit val timeout = Timeout(1.minute) implicit val clock = Clock.systemUTC val storages: Storages[Task, AkkaSource] = new DiskStorage(appConfig.storage, appConfig.digest, AttributesCache[Task, AkkaSource]) val logger: LoggingAdapter = Logging(as, getClass) logger.info("==== Cluster is Live ====") val routes: Route = Routes(storages) val httpBinding: Future[Http.ServerBinding] = { Http().bindAndHandle(routes, appConfig.http.interface, appConfig.http.port) } httpBinding onComplete { case Success(binding) => logger.info(s"Bound to ${binding.localAddress.getHostString}: ${binding.localAddress.getPort}") case Failure(th) => logger.error(th, "Failed to perform an http binding on {}:{}", appConfig.http.interface, appConfig.http.port) Await.result(as.terminate(), 10.seconds) } as.registerOnTermination { shutdownMonitoring() } // attempt to leave the cluster before shutting down val _ = sys.addShutdownHook { Await.result(as.terminate().map(_ => ()), 10.seconds) } } } // $COVERAGE-ON$
Example 43
Source File: SimpleWebSocketActor.scala From monix-sample with Apache License 2.0 | 5 votes |
package engine import akka.actor.{Actor, ActorRef, Props} import engine.SimpleWebSocketActor.Next import monix.execution.Scheduler import monix.reactive.Observable import monix.execution.Ack.Continue import monix.execution.cancelables.CompositeCancelable import org.joda.time.{DateTime, DateTimeZone} import play.api.libs.json.{JsValue, Json, Writes} import scala.concurrent.duration._ import engine.BackPressuredWebSocketActor._ class SimpleWebSocketActor[T: Writes] (producer: Observable[T], out: ActorRef)(implicit s: Scheduler) extends Actor { def receive: Receive = { case Next(jsValue) => out ! jsValue } private[this] val subscription = CompositeCancelable() override def preStart(): Unit = { super.preStart() val source = { val initial = Observable.evalOnce(initMessage(now())) val obs = initial ++ producer.map(x => Json.toJson(x)) val timeout = obs.debounce(3.seconds).map(_ => keepAliveMessage(now())) Observable.merge(obs, timeout) } subscription += source.subscribe { jsValue => self ! Next(jsValue) Continue } } override def postStop(): Unit = { subscription.cancel() super.postStop() } def now(): Long = DateTime.now(DateTimeZone.UTC).getMillis } object SimpleWebSocketActor { case class Next(value: JsValue) }
Example 44
Source File: BackPressuredWebSocketActor.scala From monix-sample with Apache License 2.0 | 5 votes |
package engine import akka.actor.{Actor, ActorRef, Props} import com.typesafe.scalalogging.LazyLogging import engine.BackPressuredWebSocketActor._ import monix.execution.Scheduler import monix.execution.rstreams.SingleAssignmentSubscription import monix.reactive.Observable import org.reactivestreams.{Subscriber, Subscription} import play.api.libs.json._ import scala.concurrent.duration._ import scala.util.Try class BackPressuredWebSocketActor[T: Writes] (producer: Observable[T], out: ActorRef)(implicit s: Scheduler) extends Actor with LazyLogging { def receive: Receive = { case JsNumber(nr) if nr > 0 => Try(nr.toLongExact).foreach(subscription.request) } private[this] val subscription = SingleAssignmentSubscription() def now(): Long = System.currentTimeMillis() override def preStart(): Unit = { super.preStart() val source = { val initial = Observable.evalOnce(initMessage(now())) val obs = initial ++ producer.map(x => Json.toJson(x)) val timeout = obs.debounceRepeated(5.seconds).map(_ => keepAliveMessage(now())) Observable .merge(obs, timeout) .whileBusyDropEventsAndSignal(nr => onOverflow(nr, now())) } source.toReactivePublisher.subscribe(new Subscriber[JsValue] { def onSubscribe(s: Subscription): Unit = { subscription := s } def onNext(json: JsValue): Unit = { out ! json } def onError(t: Throwable): Unit = { logger.warn(s"Error while serving a web-socket stream", t) out ! Json.obj( "event" -> "error", "type" -> t.getClass.getName, "message" -> t.getMessage, "timestamp" -> now()) context.stop(self) } def onComplete(): Unit = { out ! Json.obj("event" -> "complete", "timestamp" -> now()) context.stop(self) } }) } override def postStop(): Unit = { subscription.cancel() super.postStop() } } object BackPressuredWebSocketActor { def initMessage(now: Long) = { Json.obj("event" -> "init", "timestamp" -> now) } }
Example 45
Source File: Runner.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.context.monix import io.getquill.context.ContextEffect import monix.eval.Task import monix.execution.Scheduler import monix.reactive.Observable object Runner { def default = new Runner {} def using(scheduler: Scheduler) = new Runner { override def schedule[T](t: Task[T]): Task[T] = t.executeOn(scheduler, true) override def boundary[T](t: Task[T]): Task[T] = t.executeOn(scheduler, true) override def scheduleObservable[T](o: Observable[T]): Observable[T] = o.executeOn(scheduler, true) } } trait Runner extends ContextEffect[Task] { override def wrap[T](t: => T): Task[T] = Task(t) override def push[A, B](result: Task[A])(f: A => B): Task[B] = result.map(f) override def seq[A, B](list: List[Task[A]]): Task[List[A]] = Task.sequence(list) def schedule[T](t: Task[T]): Task[T] = t def scheduleObservable[T](o: Observable[T]): Observable[T] = o def boundary[T](t: Task[T]): Task[T] = t.asyncBoundary def wrapClose(t: => Unit): Task[Unit] = Task(t) }
Example 46
Source File: RunnerSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.context.monix import io.getquill.Spec import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.scalatest.matchers.should.Matchers._ import scala.util.Failure class RunnerSpec extends Spec { class SideEffect { private var state = 0 def apply() = state = 1 def applied = state == 1 } implicit val scheduler = Scheduler.global "plain runner" - { val runner = Runner.default import runner._ "should lazily evaluate" in { val sideEffect = new SideEffect val task = wrap(sideEffect()) sideEffect.applied should equal(false) task.runSyncUnsafe() sideEffect.applied should equal(true) } "should encapsulate exception throw" in { wrap(throw new RuntimeException("Surprise!")).materialize.runSyncUnsafe() should matchPattern { case Failure(e) if (e.getMessage == "Surprise!") => } } "should push an effect correctly" in { push(Task(1))(_ + 1).runSyncUnsafe() should equal(2) } "should convert a sequence correctly" in { seq(List(Task(1), Task(2), Task(3))).runSyncUnsafe() should equal(List(1, 2, 3)) } "plain schedule should be a no-op" in { val t = Task(1) (schedule(t) eq (t)) must equal(true) } "boundary operator must force async boundary" in { val (first, second) = boundary(Task(Thread.currentThread().getName)) .flatMap(prevName => Task((prevName, Thread.currentThread().getName))) .runSyncUnsafe() first must not equal (second) } } "using scheduler runner" - { val prefix = "quill-test-pool" val customScheduler = Scheduler.io(prefix) val runner = Runner.using(customScheduler) import runner._ "should run in specified scheduler" in { // the global scheduler is imported but want to explicitly tell this to run on it, just for clarity val threadName = schedule(Task(Thread.currentThread().getName)).runSyncUnsafe()(Scheduler.global, CanBlock.permit) threadName.startsWith(prefix) must equal(true) } "should async-boundary in specified scheduler" in { // the global scheduler is imported but want to explicitly tell this to run on it, just for clarity val threadName = boundary(Task(Thread.currentThread().getName)).runSyncUnsafe()(Scheduler.global, CanBlock.permit) threadName.startsWith(prefix) must equal(true) } "should async-boundary correctly" in { val prefix2 = "quill-test-pool2" // the global scheduler is imported but want to explicitly tell this to run on it, just for clarity val (first, second) = Task(Thread.currentThread().getName) .executeOn(Scheduler.io(prefix2)) .flatMap(prevName => boundary(Task((prevName, Thread.currentThread().getName)))) .runSyncUnsafe()(Scheduler.global, CanBlock.permit) first.startsWith(prefix2) must equal(true) second.startsWith(prefix) must equal(true) first must not equal second } } }
Example 47
Source File: CassandraStreamContext.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill import com.datastax.driver.core.{ Cluster, ResultSet, Row } import com.typesafe.config.Config import io.getquill.context.cassandra.util.FutureConversions._ import io.getquill.util.{ ContextLogger, LoadConfig } import monix.eval.Task import monix.execution.Scheduler import monix.execution.Scheduler.Implicits import monix.reactive.Observable import scala.jdk.CollectionConverters._ import scala.util.{ Failure, Success } class CassandraStreamContext[N <: NamingStrategy]( naming: N, cluster: Cluster, keyspace: String, preparedStatementCacheSize: Long ) extends CassandraClusterSessionContext[N](naming, cluster, keyspace, preparedStatementCacheSize) { def this(naming: N, config: CassandraContextConfig) = this(naming, config.cluster, config.keyspace, config.preparedStatementCacheSize) def this(naming: N, config: Config) = this(naming, CassandraContextConfig(config)) def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix)) private val logger = ContextLogger(classOf[CassandraStreamContext[_]]) override type Result[T] = Observable[T] override type RunQueryResult[T] = T override type RunQuerySingleResult[T] = T override type RunActionResult = Unit override type RunBatchActionResult = Unit protected def page(rs: ResultSet): Task[Iterable[Row]] = Task.defer { val available = rs.getAvailableWithoutFetching val page = rs.asScala.take(available) if (rs.isFullyFetched) Task.now(page) else Task.fromFuture(rs.fetchMoreResults().asScala(Implicits.global)).map(_ => page) } def executeQuery[T](cql: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor): Observable[T] = { Observable .fromTask(prepareRowAndLog(cql, prepare)) .mapEvalF(p => session.executeAsync(p).asScala(Implicits.global)) .flatMap(Observable.fromAsyncStateAction((rs: ResultSet) => page(rs).map((_, rs)))(_)) .takeWhile(_.nonEmpty) .flatMap(Observable.fromIterable) .map(extractor) } def executeQuerySingle[T](cql: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor): Observable[T] = executeQuery(cql, prepare, extractor) def executeAction[T](cql: String, prepare: Prepare = identityPrepare): Observable[Unit] = { Observable .fromTask(prepareRowAndLog(cql, prepare)) .mapEvalF(p => session.executeAsync(p).asScala(Implicits.global)) .map(_ => ()) } def executeBatchAction(groups: List[BatchGroup]): Observable[Unit] = Observable.fromIterable(groups).flatMap { case BatchGroup(cql, prepare) => Observable.fromIterable(prepare) .flatMap(executeAction(cql, _)) .map(_ => ()) } private def prepareRowAndLog(cql: String, prepare: Prepare = identityPrepare): Task[PrepareRow] = { Task.async0[PrepareRow] { (scheduler, callback) => implicit val executor: Scheduler = scheduler super.prepareAsync(cql) .map(prepare) .onComplete { case Success((params, bs)) => logger.logQuery(cql, params) callback.onSuccess(bs) case Failure(ex) => callback.onError(ex) } } } }
Example 48
Source File: CassandraMonixContext.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill import com.datastax.driver.core.{ Cluster, ResultSet, Row } import com.typesafe.config.Config import io.getquill.context.cassandra.CqlIdiom import io.getquill.context.monix.{ MonixContext, Runner } import io.getquill.util.{ ContextLogger, LoadConfig } import io.getquill.context.cassandra.util.FutureConversions._ import monix.eval.Task import monix.execution.Scheduler import monix.reactive.Observable import scala.jdk.CollectionConverters._ import scala.util.{ Failure, Success } class CassandraMonixContext[N <: NamingStrategy]( naming: N, cluster: Cluster, keyspace: String, preparedStatementCacheSize: Long ) extends CassandraClusterSessionContext[N](naming, cluster, keyspace, preparedStatementCacheSize) with MonixContext[CqlIdiom, N] { // not using this here override val effect = Runner.default def this(naming: N, config: CassandraContextConfig) = this(naming, config.cluster, config.keyspace, config.preparedStatementCacheSize) def this(naming: N, config: Config) = this(naming, CassandraContextConfig(config)) def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix)) private val logger = ContextLogger(classOf[CassandraMonixContext[_]]) override type StreamResult[T] = Observable[T] override type RunActionResult = Unit override type Result[T] = Task[T] override type RunQueryResult[T] = List[T] override type RunQuerySingleResult[T] = T override type RunBatchActionResult = Unit protected def page(rs: ResultSet): Task[Iterable[Row]] = Task.defer { val available = rs.getAvailableWithoutFetching val page = rs.asScala.take(available) if (rs.isFullyFetched) Task.now(page) else Task.fromFuture(rs.fetchMoreResults().asScalaWithDefaultGlobal).map(_ => page) } def streamQuery[T](fetchSize: Option[Int], cql: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor): Observable[T] = { Observable .fromTask(prepareRowAndLog(cql, prepare)) .mapEvalF(p => session.executeAsync(p).asScalaWithDefaultGlobal) .flatMap(Observable.fromAsyncStateAction((rs: ResultSet) => page(rs).map((_, rs)))(_)) .takeWhile(_.nonEmpty) .flatMap(Observable.fromIterable) .map(extractor) } def executeQuery[T](cql: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor): Task[List[T]] = { streamQuery[T](None, cql, prepare, extractor) .foldLeftL(List[T]())({ case (l, r) => r +: l }).map(_.reverse) } def executeQuerySingle[T](cql: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor): Task[T] = executeQuery(cql, prepare, extractor).map(handleSingleResult(_)) def executeAction[T](cql: String, prepare: Prepare = identityPrepare): Task[Unit] = { prepareRowAndLog(cql, prepare) .flatMap(r => Task.fromFuture(session.executeAsync(r).asScalaWithDefaultGlobal)) .map(_ => ()) } def executeBatchAction(groups: List[BatchGroup]): Task[Unit] = Observable.fromIterable(groups).flatMap { case BatchGroup(cql, prepare) => Observable.fromIterable(prepare) .flatMap(prep => Observable.fromTask(executeAction(cql, prep))) .map(_ => ()) }.completedL private def prepareRowAndLog(cql: String, prepare: Prepare = identityPrepare): Task[PrepareRow] = { Task.async0[PrepareRow] { (scheduler, callback) => implicit val executor: Scheduler = scheduler super.prepareAsync(cql) .map(prepare) .onComplete { case Success((params, bs)) => logger.logQuery(cql, params) callback.onSuccess(bs) case Failure(ex) => callback.onError(ex) } } } }
Example 49
Source File: StreamResultsOrBlowUpSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.integration import java.sql.{ Connection, ResultSet } import io.getquill._ import io.getquill.context.monix.Runner import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.scalatest.matchers.should.Matchers._ import scala.concurrent.duration.Duration class StreamResultsOrBlowUpSpec extends Spec { case class Person(name: String, age: Int) private implicit val scheduler = Scheduler.io() // set to true in order to create a ResultSet type (i.e. a rewindable one) // that will force jdbc to load the entire ResultSet into memory and crash this test. val doBlowUp = false val ctx = new PostgresMonixJdbcContext(Literal, "testPostgresDB", Runner.default) { override protected def prepareStatementForStreaming(sql: String, conn: Connection, fetchSize: Option[Int]) = { val stmt = conn.prepareStatement( sql, if (doBlowUp) ResultSet.TYPE_SCROLL_SENSITIVE else ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ) fetchSize.foreach(stmt.setFetchSize(_)) stmt } } import ctx.{ run => runQuill, _ } val numRows = 1000000L "stream a large result set without blowing up" in { val deletes = runQuill { query[Person].delete } deletes.runSyncUnsafe(Duration.Inf)(scheduler, CanBlock.permit) val inserts = quote { (numRows: Long) => infix"""insert into person (name, age) select md5(random()::text), random()*10+1 from generate_series(1, ${numRows}) s(i)""".as[Insert[Int]] } runQuill(inserts(lift(numRows))).runSyncUnsafe(Duration.Inf)(scheduler, CanBlock.permit) // not sure why but foreachL causes a OutOfMemory exception anyhow, and firstL causes a ResultSet Closed exception val result = stream(query[Person], 100) .zipWithIndex .foldLeftL(0L)({ case (totalYears, (person, index)) => { // Need to print something out as we stream or travis will thing the build is stalled and kill it with the following message: // "No output has been received in the last 10m0s..." if (index % 10000 == 0) println(s"Streaming Test Row: ${index}") totalYears + person.age } }) .runSyncUnsafe(Duration.Inf)(scheduler, CanBlock.permit) result should be > numRows } }
Example 50
Source File: PeopleMonixSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill import io.getquill.context.monix.MonixJdbcContext import io.getquill.context.sql.PeopleSpec import monix.execution.Scheduler import monix.reactive.Observable trait PeopleMonixSpec extends PeopleSpec { implicit val scheduler = Scheduler.global val context: MonixJdbcContext[_, _] import context._ def collect[T](o: Observable[T]) = o.foldLeft(List[T]())({ case (l, elem) => elem +: l }) .firstL .runSyncUnsafe() val `Ex 11 query` = quote(query[Person]) val `Ex 11 expected` = peopleEntries }
Example 51
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.oracle import io.getquill.context.sql.ProductSpec import monix.eval.Task import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- Task.sequence(productEntries.map(product => testContext.run(productInsert(lift(product))))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 52
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.oracle import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 53
Source File: ConnectionLeakTest.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.postgres import java.util.UUID import io.getquill.context.monix.Runner import io.getquill.{ JdbcContextConfig, Literal, PostgresMonixJdbcContext } import io.getquill.context.sql.ProductSpec import io.getquill.util.LoadConfig import monix.execution.Scheduler import scala.util.Random class ConnectionLeakTest extends ProductSpec { implicit val scheduler = Scheduler.global val dataSource = JdbcContextConfig(LoadConfig("testPostgresLeakDB")).dataSource val context = new PostgresMonixJdbcContext(Literal, dataSource, Runner.default) import context._ override def beforeAll = { context.run(quote(query[Product].delete)).runSyncUnsafe() () } "insert and select without leaking" in { val result = context.transaction { for { _ <- context.run { quote { query[Product].insert( lift(Product(1, UUID.randomUUID().toString, Random.nextLong())) ) } } result <- context.run { query[Product].filter(p => query[Product].map(_.id).max.exists(_ == p.id)) } } yield (result) } .map(_.headOption.map(_.id)) .runSyncUnsafe() Thread.sleep(2000) result mustEqual Option(1) dataSource.getHikariPoolMXBean.getActiveConnections mustEqual 0 context.close() } }
Example 54
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.postgres import io.getquill.context.sql.ProductSpec import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- testContext.run(liftQuery(productEntries).foreach(e => productInsert(e))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 55
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.postgres import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 56
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.sqlserver import io.getquill.context.sql.ProductSpec import monix.eval.Task import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- Task.sequence(productEntries.map(product => testContext.run(productInsert(lift(product))))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 57
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.sqlserver import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) implicit val im = insertMeta[Product](_.id) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 58
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.mysql import io.getquill.context.sql.ProductSpec import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- testContext.run(liftQuery(productEntries).foreach(e => productInsert(e))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 59
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.mysql import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 60
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.sqlite import io.getquill.context.sql.ProductSpec import monix.eval.Task import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- Task.sequence(productEntries.map(product => testContext.run(productInsert(lift(product))))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 61
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.sqlite import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 62
Source File: ProductJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.h2 import io.getquill.context.sql.ProductSpec import monix.execution.Scheduler class ProductJdbcSpec extends ProductSpec { val context = testContext import testContext._ implicit val scheduler = Scheduler.global override def beforeAll = { testContext.run(quote(query[Product].delete)).runSyncUnsafe() () } "Product" - { "Insert multiple products" in { val (inserted, product) = (for { i <- testContext.run(liftQuery(productEntries).foreach(e => productInsert(e))) ps <- testContext.run(productById(lift(i(2)))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual productEntries(2).description product.id mustEqual inserted(2) } "Single insert product" in { val (inserted, product) = (for { i <- testContext.run(productSingleInsert) ps <- testContext.run(productById(lift(i))) } yield (i, ps.head)).runSyncUnsafe() product.description mustEqual "Window" product.id mustEqual inserted } "Single insert with inlined free variable" in { val prd = Product(0L, "test1", 1L) val (inserted, returnedProduct) = (for { i <- testContext.run { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test1" returnedProduct.sku mustEqual 1L returnedProduct.id mustEqual inserted } "Single insert with free variable and explicit quotation" in { val prd = Product(0L, "test2", 2L) val q1 = quote { product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) } val (inserted, returnedProduct) = (for { i <- testContext.run(q1) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test2" returnedProduct.sku mustEqual 2L returnedProduct.id mustEqual inserted } "Single product insert with a method quotation" in { val prd = Product(0L, "test3", 3L) val (inserted, returnedProduct) = (for { i <- testContext.run(productInsert(lift(prd))) rps <- testContext.run(productById(lift(i))) } yield (i, rps.head)).runSyncUnsafe() returnedProduct.description mustEqual "test3" returnedProduct.sku mustEqual 3L returnedProduct.id mustEqual inserted } } }
Example 63
Source File: PrepareJdbcSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.h2 import java.sql.ResultSet import io.getquill.PrepareMonixJdbcSpecBase import monix.execution.Scheduler import org.scalatest.BeforeAndAfter class PrepareJdbcSpec extends PrepareMonixJdbcSpecBase with BeforeAndAfter { val context = testContext import testContext._ implicit val scheduler = Scheduler.global before { testContext.run(query[Product].delete).runSyncUnsafe() } def productExtractor = (rs: ResultSet) => materializeQueryMeta[Product].extract(rs) val prepareQuery = prepare(query[Product]) "single" in { val prepareInsert = prepare(query[Product].insert(lift(productEntries.head))) singleInsert(dataSource.getConnection)(prepareInsert).runSyncUnsafe() mustEqual false extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === List(productEntries.head) } "batch" in { val prepareBatchInsert = prepare( liftQuery(withOrderedIds(productEntries)).foreach(p => query[Product].insert(p)) ) batchInsert(dataSource.getConnection)(prepareBatchInsert).runSyncUnsafe().distinct mustEqual List(false) extractProducts(dataSource.getConnection)(prepareQuery).runSyncUnsafe() === withOrderedIds(productEntries) } }
Example 64
Source File: ResultSetIteratorSpec.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill import io.getquill.context.monix.Runner import io.getquill.util.LoadConfig import monix.eval.Task import monix.execution.Scheduler import org.scalatest.BeforeAndAfterAll import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.must.Matchers import org.scalatest.matchers.should.Matchers._ import scala.collection.mutable.ArrayBuffer class ResultSetIteratorSpec extends AnyFreeSpec with Matchers with BeforeAndAfterAll { val ds = JdbcContextConfig(LoadConfig("testPostgresDB")).dataSource implicit val scheduler = Scheduler.global val ctx = new PostgresMonixJdbcContext(Literal, ds, Runner.default) import ctx._ case class Person(name: String, age: Int) val peopleInsert = quote((p: Person) => query[Person].insert(p)) val peopleEntries = List( Person("Alex", 60), Person("Bert", 55), Person("Cora", 33) ) override def beforeAll = { ctx.transaction { for { _ <- ctx.run(query[Person].delete) _ <- ctx.run(liftQuery(peopleEntries).foreach(p => peopleInsert(p))) } yield () }.runSyncUnsafe() } "traverses correctly" in { val results = Task(ds.getConnection).bracket { conn => Task { val stmt = conn.prepareStatement("select * from person") val rs = new ResultSetIterator[String](stmt.executeQuery(), extractor = (rs) => { rs.getString(1) }) val accum = ArrayBuffer[String]() while (rs.hasNext) accum += rs.next() accum } } { conn => Task(conn.close()) }.runSyncUnsafe() results should contain theSameElementsAs (peopleEntries.map(_.name)) } "can take head element" in { val result = Task(ds.getConnection).bracket { conn => Task { val stmt = conn.prepareStatement("select * from person where name = 'Alex'") val rs = new ResultSetIterator(stmt.executeQuery(), extractor = (rs) => { rs.getString(1) }) rs.head } } { conn => Task(conn.close()) }.runSyncUnsafe() result must equal("Alex") } }
Example 65
Source File: AuthDirectives.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.directives import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.directives.Credentials import akka.http.scaladsl.server.{Directive0, Directive1} import cats.implicits._ import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.iam.acls.Acls import ch.epfl.bluebrain.nexus.iam.auth.AccessToken import ch.epfl.bluebrain.nexus.iam.config.AppConfig.HttpConfig import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.types.IamError.AccessDenied import ch.epfl.bluebrain.nexus.iam.types.{Caller, Permission} import ch.epfl.bluebrain.nexus.rdf.Iri.{AbsoluteIri, Path} import monix.eval.Task import monix.execution.Scheduler import scala.concurrent.Future object AuthDirectives { def authorizeFor(permission: Permission)( implicit acls: Acls[Task], s: Scheduler, c: Caller, hc: HttpConfig ): Directive0 = extractResourceAddress.flatMap { address => onSuccess { acls .hasPermission(Path./, permission, ancestors = false) .ifM(Task.unit, Task.raiseError(AccessDenied(address, permission))) .runToFuture } } }
Example 66
Source File: instances.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam.marshallers import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller import akka.http.scaladsl.marshalling._ import akka.http.scaladsl.model.MediaTypes.`application/json` import akka.http.scaladsl.model._ import ch.epfl.bluebrain.nexus.commons.circe.syntax._ import ch.epfl.bluebrain.nexus.commons.http.JsonLdCirceSupport.OrderedKeys import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._ import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom import ch.epfl.bluebrain.nexus.iam.acls.AclRejection import ch.epfl.bluebrain.nexus.iam.config.AppConfig._ import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsRejection import ch.epfl.bluebrain.nexus.iam.realms.RealmRejection import ch.epfl.bluebrain.nexus.iam.types.IamError.InternalError import ch.epfl.bluebrain.nexus.iam.types.{IamError, ResourceRejection} import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport import io.circe._ import io.circe.syntax._ import monix.eval.Task import monix.execution.Scheduler import scala.collection.immutable.Seq import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration object instances extends FailFastCirceSupport { implicit val finiteDurationEncoder: Encoder[FiniteDuration] = Encoder.encodeString.contramap(fd => s"${fd.toMillis} ms") implicit val resourceRejectionEncoder: Encoder[ResourceRejection] = Encoder.instance { case r: AclRejection => Encoder[AclRejection].apply(r) case r: RealmRejection => Encoder[RealmRejection].apply(r) case r: PermissionsRejection => Encoder[PermissionsRejection].apply(r) case _ => Encoder[IamError].apply(InternalError("unspecified")) } implicit val resourceRejectionStatusFrom: StatusFrom[ResourceRejection] = StatusFrom { case r: AclRejection => AclRejection.aclRejectionStatusFrom(r) case r: RealmRejection => RealmRejection.realmRejectionStatusFrom(r) case r: PermissionsRejection => PermissionsRejection.permissionsRejectionStatusFrom(r) } override def unmarshallerContentTypes: Seq[ContentTypeRange] = List(`application/json`, `application/ld+json`, `application/sparql-results+json`) implicit final def rejection[A <: ResourceRejection: Encoder]( implicit statusFrom: StatusFrom[A], printer: Printer = Printer.noSpaces.copy(dropNullValues = true), ordered: OrderedKeys = orderedKeys ): ToResponseMarshaller[A] = { val marshallers = Seq(`application/ld+json`, `application/json`).map { contentType => Marshaller.withFixedContentType[A, HttpResponse](contentType) { rejection => HttpResponse( status = statusFrom(rejection), entity = HttpEntity(contentType, printer.print(rejection.asJson.sortKeys)) ) } } Marshaller.oneOf(marshallers: _*) } implicit class EitherTask[R <: ResourceRejection, A](task: Task[Either[R, A]])(implicit s: Scheduler) { def runWithStatus(code: StatusCode): Future[Either[R, (StatusCode, A)]] = task.map(_.map(code -> _)).runToFuture } implicit class OptionTask[A](task: Task[Option[A]])(implicit s: Scheduler) { def runNotFound: Future[A] = task.flatMap { case Some(a) => Task.pure(a) case None => Task.raiseError(IamError.NotFound) }.runToFuture } }
Example 67
Source File: RepairFromMessages.scala From nexus-iam with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.iam import java.net.URLDecoder import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.PersistenceQuery import ch.epfl.bluebrain.nexus.iam.acls.Acls import ch.epfl.bluebrain.nexus.iam.permissions.Permissions import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.types.Label import ch.epfl.bluebrain.nexus.rdf.Iri.Path import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import scala.concurrent.Future object RepairFromMessages { // $COVERAGE-OFF$ private val log = Logger[RepairFromMessages.type] def repair( p: Permissions[Task], r: Realms[Task], a: Acls[Task] )(implicit as: ActorSystem, sc: Scheduler, pm: CanBlock): Unit = { val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) pq.currentPersistenceIds() .mapAsync(1) { case PermissionsId() => p.agg.currentState(p.persistenceId).runToFuture case RealmId(label) => r.agg.currentState(label.value).runToFuture case AclId(path) => a.agg.currentState(path.asString).runToFuture case other => log.warn(s"Unknown persistence id '$other'") Future.successful(()) } .runFold(0) { case (acc, _) => if (acc % 100 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .runSyncDiscard() log.info("Repair from messages table completed.") } sealed abstract class PersistenceId(prefix: String) { private val len = prefix.length protected def dropPrefix(arg: String): Option[String] = if (arg.startsWith(prefix)) Some(arg.drop(len)) else None } object RealmId extends PersistenceId("realms-") { def unapply(arg: String): Option[Label] = dropPrefix(arg).map(Label.unsafe) } object AclId extends PersistenceId("acls-") { def unapply(arg: String): Option[Path] = dropPrefix(arg).flatMap(str => Path(URLDecoder.decode(str, "UTF-8")).toOption) } object PermissionsId { def unapply(arg: String): Boolean = arg == "permissions-permissions" } implicit class RichFuture[A](val future: Future[A]) extends AnyVal { def runSyncDiscard()(implicit s: Scheduler, permit: CanBlock): Unit = Task.fromFuture(future).map(_ => ()).runSyncUnsafe() } // $COVERAGE-ON$ }
Example 68
Source File: HttpMockServerResource.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.http.server import com.github.agourlay.cornichon.core.{ RunState, Session } import com.github.agourlay.cornichon.dsl.BlockScopedResource import com.github.agourlay.cornichon.http.server.HttpMockServerResource.SessionKeys._ import io.circe.Json import monix.eval.Task import monix.execution.Scheduler case class HttpMockServerResource(interface: Option[String], label: String, portRange: Option[Range]) extends BlockScopedResource { implicit val scheduler = Scheduler.Implicits.global val sessionTarget: String = label val openingTitle: String = s"Starting HTTP mock server '$label'" val closingTitle: String = s"Shutting down HTTP mock server '$label'" def use[A](outsideRunState: RunState)(f: RunState => Task[A]): Task[(Session, A)] = { val mockRequestHandler = new MockServerRequestHandler() val initSession: String => Session = id => Session.newEmpty.addValueUnsafe(s"$label-url", id) val resourceContext: RunState => Session => RunState = r1 => s1 => r1.mergeSessions(s1) val runWithServer = initSession.andThen(resourceContext(outsideRunState)).andThen(f) val mockServer = new MockHttpServer(interface, portRange, mockRequestHandler.mockService)(runWithServer) mockServer.useServer().map { res => val resourceResults = requestsResults(mockRequestHandler) (resourceResults, res) } } def requestsResults(mockRequestHandler: MockServerRequestHandler): Session = { val jsonRequests = mockRequestHandler.fetchRecordedRequestsAsJson() Session.newEmpty .addValueUnsafe(s"$sessionTarget$receivedBodiesSuffix", Json.fromValues(jsonRequests).spaces2) .addValueUnsafe(s"$sessionTarget$nbReceivedCallsSuffix", jsonRequests.size.toString) } } object HttpMockServerResource { object SessionKeys { val nbReceivedCallsSuffix = "-nb-received-calls" val receivedBodiesSuffix = "-received-bodies" } }
Example 69
Source File: CheckStepBench.scala From cornichon with Apache License 2.0 | 5 votes |
package step import java.util.concurrent.{ ExecutorService, Executors } import com.github.agourlay.cornichon.core._ import monix.execution.Scheduler import org.openjdk.jmh.annotations._ import com.github.agourlay.cornichon.steps.check.checkModel._ import com.github.agourlay.cornichon.steps.cats.EffectStep import scala.concurrent.Await import scala.concurrent.duration.Duration import step.JsonStepBench._ @State(Scope.Benchmark) @BenchmarkMode(Array(Mode.Throughput)) @Warmup(iterations = 10) @Measurement(iterations = 10) @Fork(value = 1, jvmArgsAppend = Array( "-XX:+FlightRecorder", "-XX:StartFlightRecording=filename=./CheckStepBench-profiling-data.jfr,name=profile,settings=profile", "-Xmx1G")) class CheckStepBench { //sbt:benchmarks> jmh:run .*CheckStep.* -prof gc -foe true -gc true -rf csv @Param(Array("10", "20", "50", "100", "200")) var transitionNumber: String = "" var es: ExecutorService = _ var scheduler: Scheduler = _ @Setup(Level.Trial) final def beforeAll(): Unit = { es = Executors.newFixedThreadPool(1) scheduler = Scheduler(es) } @TearDown(Level.Trial) final def afterAll(): Unit = { es.shutdown() } @Benchmark def runModel() = { val checkStep = CheckModelStep(maxNumberOfRuns = 1, maxNumberOfTransitions = transitionNumber.toInt, CheckStepBench.modelRunner) val s = Scenario("scenario with checkStep", checkStep :: Nil) val f = ScenarioRunner.runScenario(session)(s) val res = Await.result(f.runToFuture(scheduler), Duration.Inf) assert(res.isSuccess) } } object CheckStepBench { def integerGen(rc: RandomContext): ValueGenerator[Int] = ValueGenerator( name = "integer", gen = () => rc.nextInt(10000)) def dummyProperty1(name: String): PropertyN[Int, NoValue, NoValue, NoValue, NoValue, NoValue] = Property1( description = name, invariant = g => EffectStep.fromSyncE("add generated", _.session.addValue("generated", g().toString))) val starting = dummyProperty1("starting action") val otherAction = dummyProperty1("other action") val otherActionTwo = dummyProperty1("other action two") val transitions = Map( starting -> ((100, otherAction) :: Nil), otherAction -> ((100, otherActionTwo) :: Nil), otherActionTwo -> ((100, otherAction) :: Nil)) val model = Model("model with empty transition for starting", starting, transitions) val modelRunner = ModelRunner.make(integerGen)(model) }
Example 70
Source File: RunScenarioBench.scala From cornichon with Apache License 2.0 | 5 votes |
package scenario import java.util.concurrent.{ ExecutorService, Executors } import cats.instances.int._ import com.github.agourlay.cornichon.core.{ ScenarioRunner, Scenario, Session } import com.github.agourlay.cornichon.steps.cats.EffectStep import com.github.agourlay.cornichon.steps.regular.assertStep.{ AssertStep, Assertion, GenericEqualityAssertion } import org.openjdk.jmh.annotations._ import scenario.RunScenarioBench._ import monix.execution.Scheduler import scala.concurrent.Await import scala.concurrent.duration._ @State(Scope.Benchmark) @BenchmarkMode(Array(Mode.Throughput)) @Warmup(iterations = 10) @Measurement(iterations = 10) @Fork(value = 1, jvmArgsAppend = Array( "-XX:+FlightRecorder", "-XX:StartFlightRecording=filename=./RunScenarioBench-profiling-data.jfr,name=profile,settings=profile", "-Xmx1G")) class RunScenarioBench { //sbt:benchmarks> jmh:run .*RunScenario.* -prof gc -foe true -gc true -rf csv @Param(Array("10", "20", "50", "100", "200")) var stepsNumber: String = "" var es: ExecutorService = _ var scheduler: Scheduler = _ @Setup(Level.Trial) final def beforeAll(): Unit = { es = Executors.newFixedThreadPool(1) scheduler = Scheduler(es) } @TearDown(Level.Trial) final def afterAll(): Unit = { es.shutdown() } @Benchmark def lotsOfSteps() = { val half = stepsNumber.toInt / 2 val assertSteps = List.fill(half)(assertStep) val effectSteps = List.fill(half)(effectStep) val scenario = Scenario("test scenario", setupSession +: (assertSteps ++ effectSteps)) val f = ScenarioRunner.runScenario(Session.newEmpty)(scenario) val res = Await.result(f.runToFuture(scheduler), Duration.Inf) assert(res.isSuccess) } } object RunScenarioBench { val setupSession = EffectStep.fromSyncE("setup session", _.session.addValues("v1" -> "2", "v2" -> "1")) val assertStep = AssertStep( "addition step", sc => Assertion.either { for { two <- sc.session.get("v1").map(_.toInt) one <- sc.session.get("v2").map(_.toInt) } yield GenericEqualityAssertion(two + one, 3) }) val effectStep = EffectStep.fromSync("identity", _.session) }
Example 71
Source File: RequestEffectBench.scala From cornichon with Apache License 2.0 | 5 votes |
package httpService import java.util.concurrent.{ ExecutorService, Executors } import cats.instances.string._ import com.github.agourlay.cornichon.core.{ Config, ScenarioContext } import com.github.agourlay.cornichon.http.{ HttpMethods, HttpRequest, HttpService } import org.openjdk.jmh.annotations._ import RequestEffectBench._ import com.github.agourlay.cornichon.http.client.NoOpHttpClient import monix.execution.Scheduler import scala.concurrent.Await import scala.concurrent.duration._ @State(Scope.Benchmark) @BenchmarkMode(Array(Mode.Throughput)) @Warmup(iterations = 10) @Measurement(iterations = 10) @Fork(value = 1, jvmArgsAppend = Array( "-XX:+FlightRecorder", "-XX:StartFlightRecording=filename=./RequestEffectBench-profiling-data.jfr,name=profile,settings=profile", "-Xmx1G")) class RequestEffectBench { //sbt:benchmarks> jmh:run .*RequestEffect.* var es: ExecutorService = _ val client = new NoOpHttpClient var httpService: HttpService = _ @Setup(Level.Trial) final def beforeAll(): Unit = { es = Executors.newFixedThreadPool(1) val scheduler = Scheduler(es) httpService = new HttpService("", 2000.millis, client, Config())(scheduler) } @TearDown(Level.Trial) final def afterAll(): Unit = { es.shutdown() } @Benchmark def singleRequest() = { val f = httpService.requestEffect(request) val res = Await.result(f(scenarioContext), Duration.Inf) assert(res.isRight) } } object RequestEffectBench { val scenarioContext = ScenarioContext.empty val request = HttpRequest[String]( method = HttpMethods.GET, url = "https://myUrl/my/segment", body = Some(""" { "k1":"v1", "k2":"v2","k3":"v3","k4":"v4" } """), params = ("q1", "v1") :: ("q2", "v2") :: ("q3", "v3") :: Nil, headers = ("h1", "v1") :: ("h2", "v2") :: ("h3", "v3") :: Nil) }
Example 72
Source File: TurnstileAPI.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.framework.examples.propertyCheck.turnstile import com.github.agourlay.cornichon.framework.examples.HttpServer import monix.eval.Task import monix.execution.atomic.AtomicBoolean import monix.execution.{ CancelableFuture, Scheduler } import org.http4s._ import org.http4s.implicits._ import org.http4s.dsl._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder class TurnstileAPI extends Http4sDsl[Task] { implicit val s = Scheduler.Implicits.global private val turnstileLocked = AtomicBoolean(true) private val turnstileService = HttpRoutes.of[Task] { case POST -> Root / "push-coin" => if (turnstileLocked.get()) { turnstileLocked.set(false) Ok("payment accepted") } else BadRequest("payment refused") case POST -> Root / "walk-through" => if (turnstileLocked.get()) BadRequest("door blocked") else { turnstileLocked.set(true) Ok("door turns") } } private val routes = Router( "/" -> turnstileService ) def start(httpPort: Int): CancelableFuture[HttpServer] = BlazeServerBuilder[Task](executionContext = s) .bindHttp(httpPort, "localhost") .withoutBanner .withNio2(true) .withHttpApp(routes.orNotFound) .allocated .map { case (_, stop) => new HttpServer(stop) } .runToFuture }
Example 73
Source File: ReverseAPI.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.framework.examples.propertyCheck.stringReverse import com.github.agourlay.cornichon.framework.examples.HttpServer import monix.eval.Task import monix.execution.{ CancelableFuture, Scheduler } import org.http4s._ import org.http4s.implicits._ import org.http4s.dsl._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder class ReverseAPI extends Http4sDsl[Task] { implicit val s = Scheduler.Implicits.global object WordQueryParamMatcher extends QueryParamDecoderMatcher[String]("word") private val reverseService = HttpRoutes.of[Task] { case POST -> Root / "double-reverse" :? WordQueryParamMatcher(word) => Ok(word.reverse.reverse) } private val routes = Router( "/" -> reverseService ) def start(httpPort: Int): CancelableFuture[HttpServer] = BlazeServerBuilder[Task](executionContext = s) .bindHttp(httpPort, "localhost") .withoutBanner .withNio2(true) .withHttpApp(routes.orNotFound) .allocated .map { case (_, stop) => new HttpServer(stop) } .runToFuture }
Example 74
Source File: BaseFeature.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.dsl import java.util.concurrent.ConcurrentLinkedDeque import com.github.agourlay.cornichon.core.{ Config, Done, FeatureDef, Step } import com.github.agourlay.cornichon.matchers.Matcher import com.github.agourlay.cornichon.resolver.Mapper import monix.execution.Scheduler import pureconfig.error.{ ConvertFailure, KeyNotFound } import scala.annotation.tailrec import scala.collection.mutable.ListBuffer import scala.concurrent.Future trait BaseFeature { protected[cornichon] val beforeFeature: ListBuffer[() => Unit] = ListBuffer.empty protected[cornichon] val afterFeature: ListBuffer[() => Unit] = ListBuffer.empty protected[cornichon] val beforeEachScenario: ListBuffer[Step] = ListBuffer.empty protected[cornichon] val afterEachScenario: ListBuffer[Step] = ListBuffer.empty private[cornichon] lazy val config = BaseFeature.config lazy val executeScenariosInParallel: Boolean = config.executeScenariosInParallel lazy val seed: Option[Long] = None // Convenient implicits for the custom DSL implicit lazy val ec = Scheduler.Implicits.global def feature: FeatureDef def registerExtractors: Map[String, Mapper] = Map.empty def registerMatchers: List[Matcher] = Nil def beforeFeature(before: => Unit): Unit = beforeFeature += (() => before) def afterFeature(after: => Unit): Unit = (() => after) +=: afterFeature def beforeEachScenario(step: Step): Unit = beforeEachScenario += step def afterEachScenario(step: Step): Unit = step +=: afterEachScenario } // Protect and free resources object BaseFeature { import pureconfig.generic.auto._ import pureconfig.ConfigSource import pureconfig.error.{ ConfigReaderException, ConfigReaderFailures } lazy val config = ConfigSource.default.at("cornichon").load[Config] match { case Right(v) => v case Left(ConfigReaderFailures(ConvertFailure(KeyNotFound("cornichon", _), _, _), _*)) => Config() case Left(failures) => throw new ConfigReaderException[Config](failures) } private val hooks = new ConcurrentLinkedDeque[() => Future[_]]() def addShutdownHook(h: () => Future[_]): Unit = hooks.push(h) def shutDownGlobalResources(): Future[Done] = { import scala.concurrent.ExecutionContext.Implicits.global @tailrec def clearHooks(previous: Future[Any] = Future.successful[Any](())): Future[Any] = Option(hooks.poll()) match { case None => previous case Some(f) => clearHooks { previous.flatMap { _ => f().recover { case _ => Done } } } } clearHooks().map(_ => Done) } }
Example 75
Source File: EffectStep.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.steps.cats import cats.data.{ EitherT, NonEmptyList } import cats.effect.Effect import cats.syntax.either._ import com.github.agourlay.cornichon.core.ScenarioRunner.{ errorsToFailureStep, successLog } import com.github.agourlay.cornichon.core._ import monix.eval.Task import monix.execution.Scheduler import scala.concurrent.duration.Duration case class EffectStep[F[_]: Effect](title: String, effect: ScenarioContext => F[Either[CornichonError, Session]], show: Boolean = true) extends SessionValueStep { def setTitle(newTitle: String): Step = copy(title = newTitle) override def runSessionValueStep(runState: RunState): Task[Either[NonEmptyList[CornichonError], Session]] = Task.fromEffect(effect(runState.scenarioContext)).map(_.leftMap(NonEmptyList.one)) override def onError(errors: NonEmptyList[CornichonError], runState: RunState, executionTime: Duration): (LogInstruction, FailedStep) = errorsToFailureStep(this, runState.depth, errors, Some(executionTime)) override def logOnSuccess(result: Session, runState: RunState, executionTime: Duration): LogInstruction = successLog(title, runState.depth, show, executionTime) } object EffectStep { def fromEitherT[F[_]: Effect](title: String, effect: ScenarioContext => EitherT[F, CornichonError, Session], show: Boolean = true): Step = { val effectT: ScenarioContext => F[Either[CornichonError, Session]] = s => effect(s).value EffectStep(title, effectT, show) } def fromSync(title: String, effect: ScenarioContext => Session, show: Boolean = true): Step = { import Scheduler.Implicits.global val effectF: ScenarioContext => Task[Either[CornichonError, Session]] = s => Task.now(effect(s).asRight) EffectStep(title, effectF, show) } def fromSyncE(title: String, effect: ScenarioContext => Either[CornichonError, Session], show: Boolean = true): Step = { import Scheduler.Implicits.global val effectF: ScenarioContext => Task[Either[CornichonError, Session]] = s => Task.now(effect(s)) EffectStep(title, effectF, show) } def fromAsync[F[_]: Effect](title: String, effect: ScenarioContext => F[Session], show: Boolean = true): Step = { import Scheduler.Implicits.global val effectF: ScenarioContext => Task[Either[CornichonError, Session]] = s => Task.fromEffect(effect(s)).map(Right.apply) EffectStep(title, effectF, show) } }
Example 76
Source File: DoobieInstancesSuite.scala From tofu with Apache License 2.0 | 5 votes |
package tofu.doobie import cats.Applicative import cats.data.ReaderT import cats.effect.{IO, SyncIO} import com.github.ghik.silencer.silent import doobie.ConnectionIO import monix.eval.{Coeval, Task} import monix.execution.Scheduler import tofu.doobie.instances.implicits._ import tofu.env.Env import tofu.lift.Lift import tofu.zioInstances.implicits._ import zio.interop.catz._ object DoobieInstancesSuite { def summonImplicitsViaLiftToIO[F[_]: Applicative, R](implicit L: Lift[F, IO]): Unit = { Lift[F, ConnectionIO] Lift[F, ConnectionRIO[R, *]] Lift[ReaderT[F, R, *], ConnectionRIO[R, *]] () } def summonCatsEffectImplicits[R](): Unit = { Lift[SyncIO, ConnectionIO] Lift[SyncIO, ConnectionRIO[R, *]] Lift[ReaderT[SyncIO, R, *], ConnectionRIO[R, *]] Lift[IO, ConnectionIO] Lift[IO, ConnectionRIO[R, *]] Lift[ReaderT[IO, R, *], ConnectionRIO[R, *]] () } def summonMonixImplicitsViaScheduler[R](implicit sc: Scheduler): Unit = { Lift[Coeval, ConnectionIO] Lift[Coeval, ConnectionRIO[R, *]] Lift[ReaderT[Coeval, R, *], ConnectionRIO[R, *]] Lift[Task, ConnectionIO] Lift[Task, ConnectionRIO[R, *]] Lift[ReaderT[Task, R, *], ConnectionRIO[R, *]] Lift[Env[R, *], ConnectionRIO[R, *]] () } def summonMonixImplicitsUnambiguously[R](implicit @silent sc: Scheduler, L: Lift[Task, IO]): Unit = { Lift[Task, ConnectionIO] Lift[Task, ConnectionRIO[R, *]] Lift[ReaderT[Task, R, *], ConnectionRIO[R, *]] () } def summonZioImplicits[R](): zio.Task[Unit] = zio.Task.concurrentEffect.map { implicit CE => Lift[zio.Task, ConnectionIO] Lift[zio.Task, ConnectionRIO[R, *]] Lift[zio.RIO[R, *], ConnectionRIO[R, *]] () } def summonLiftConnectionIO[R](): Unit = { LiftConnectionIO[ConnectionIO] LiftConnectionIO[ConnectionRIO[R, *]] () } }
Example 77
Source File: EnvInstances.scala From tofu with Apache License 2.0 | 5 votes |
package tofu.env import cats.arrow.{ArrowChoice, FunctionK, Profunctor} import cats.effect.IO import cats.{Applicative, Monad, Parallel, ~>} import monix.eval.{Task, TaskLift} import monix.execution.Scheduler import tofu.lift.{UnliftIO, UnsafeExecFuture} import tofu.optics.Contains import tofu.syntax.funk._ import scala.concurrent.Future private[env] trait EnvInstances { self: Env.type => private object anyEnvInstance extends EnvFunctorstance[Any] final implicit def envInstance[E]: EnvFunctorstance[E] = anyEnvInstance.asInstanceOf[EnvFunctorstance[E]] private object envParallelInstance extends Applicative[Env[Any, *]] { override def pure[A](x: A): Env[Any, A] = Env.pure(x) override def ap[A, B](ff: Env[Any, A => B])(fa: Env[Any, A]): Env[Any, B] = Env.parMap2(ff, fa)(_.apply(_)) override def map2[A, B, Z](fa: Env[Any, A], fb: Env[Any, B])(f: (A, B) => Z): Env[Any, Z] = Env.parMap2(fa, fb)(f) override val unit: Env[Any, Unit] = Env.unit override def map[A, B](fa: Env[Any, A])(f: A => B): Env[Any, B] = fa.map(f) override def replicateA[A](n: Int, fa: Env[Any, A]): Env[Any, List[A]] = fa.mapTask(t => Task.parSequence(Iterable.fill(n)(t)).map(_.toList)) } private object anyEnvParallelInstance extends Parallel[Env[Any, *]] { type F[a] = Env[Any, a] override def applicative: Applicative[Env[Any, *]] = envParallelInstance override def monad: Monad[Env[Any, *]] = anyEnvInstance override val sequential: ~>[Env[Any, *], Env[Any, *]] = FunctionK.id override val parallel: ~>[Env[Any, *], Env[Any, *]] = FunctionK.id } final implicit def envParallelInstance[E]: Parallel[Env[E, *]] = anyEnvParallelInstance.asInstanceOf[Parallel[Env[E, *]]] final implicit val envProfuctorInstance: Profunctor[Env] with ArrowChoice[Env] = new Profunctor[Env] with ArrowChoice[Env] { override def choose[A, B, C, D](f: Env[A, C])(g: Env[B, D]): Env[Either[A, B], Either[C, D]] = Env { case Left(a) => f.run(a).map(Left(_)) case Right(b) => g.run(b).map(Right(_)) } override def lift[A, B](f: A => B): Env[A, B] = Env(a => Task.pure(f(a))) override def first[A, B, C](fa: Env[A, B]): Env[(A, C), (B, C)] = fa.first[C] override def second[A, B, C](fa: Env[A, B]): Env[(C, A), (C, B)] = fa.second[C] override def compose[A, B, C](f: Env[B, C], g: Env[A, B]): Env[A, C] = f.compose(g) override def rmap[A, B, C](fab: Env[A, B])(f: B => C): Env[A, C] = fab.map(f) override def lmap[A, B, C](fab: Env[A, B])(f: C => A): Env[C, B] = fab.localP(f) override def id[A]: Env[A, A] = Env.context override def dimap[A, B, C, D](fab: Env[A, B])(f: C => A)(g: B => D): Env[C, D] = fab.dimap(f)(g) override def split[A, B, C, D](f: Env[A, B], g: Env[C, D]): Env[(A, C), (B, D)] = f.split(g) override def left[A, B, C](fab: Env[A, B]): Env[Either[A, C], Either[B, C]] = fab.left[C] override def right[A, B, C](fab: Env[A, B]): Env[Either[C, A], Either[C, B]] = fab.right[C] override def choice[A, B, C](f: Env[A, C], g: Env[B, C]): Env[Either[A, B], C] = f.choice(g) override def merge[A, B, C](f: Env[A, B], g: Env[A, C]): Env[A, (B, C)] = Env.parZip2(f, g) } final implicit def envUnliftSubContext[E, E1: E Contains *]: EnvUnliftSubContext[E, E1] = new EnvUnliftSubContext def envUnsafeExecFuture[E](implicit sc: Scheduler): UnsafeExecFuture[Env[E, *]] = new UnsafeExecFuture[Env[E, *]] { def lift[A](fa: Future[A]): Env[E, A] = Env.fromFuture(fa) def unlift: Env[E, Env[E, *] ~> Future] = Env.fromFunc(r => makeFunctionK(_.run(r).runToFuture)) } implicit def envUnliftIO[E](implicit toIO: TaskLift[IO]): UnliftIO[Env[E, *]] = new UnliftIO[Env[E, *]] { def lift[A](fa: IO[A]): Env[E, A] = Env.fromIO(fa) def unlift: Env[E, Env[E, *] ~> IO] = Env.fromFunc(r => funK(_.run(r).to[IO])) } }
Example 78
Source File: EnvFunctions.scala From tofu with Apache License 2.0 | 5 votes |
package tofu.env import java.util.concurrent.TimeUnit.MILLISECONDS import cats.Eval import cats.data.ReaderT import cats.effect._ import monix.eval.{Coeval, Task} import monix.execution.Scheduler import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.Try private[env] trait EnvFunctions extends EnvProducts with EnvTraversing with EnvRacing with EnvSyntax with EnvTransformations { self: Env.type => def apply[E, A](f: E => Task[A]): Env[E, A] = EnvCtx(f) def later[E, A](x: => A): Env[E, A] = fromTask(Task.delay(x)) def pure[E, A](x: A): Env[E, A] = fromTask(Task.pure(x)) def context[E]: Env[E, E] = Env(ctx => Task.now(ctx)) def withContextNow[E, A](f: E => A): Env[E, A] = Env(ctx => Task.now(f(ctx))) def withContext[E, A](f: E => Env[E, A]): Env[E, A] = Env(ctx => f(ctx).run(ctx)) def withContextFork[E, A](f: E => A): Env[E, A] = Env(ctx => Task(f(ctx))) def withContextDelay[E, A](f: E => A): Env[E, A] = Env(ctx => Task.delay(f(ctx))) private[this] val anyUnit: Env[Any, Unit] = fromTask(Task.unit) def unit[E]: Env[E, Unit] = anyUnit.asInstanceOf[Env[E, Unit]] def scheduler[E]: Env[E, Scheduler] = fromTask(Task.deferAction(scheduler => Task.pure(scheduler))) def millis[E]: Env[E, Long] = fromTask(Task.deferAction(scheduler => Task.pure(scheduler.clockRealTime(MILLISECONDS)))) def shift[E]: Env[E, Unit] = fromTask(Task.shift) def shift[E](ec: ExecutionContext): Env[E, Unit] = fromTask(Task.shift(ec)) def sleep[E](duration: FiniteDuration): Env[E, Unit] = fromTask(Task.sleep(duration)) def fromTask[E, A](task: Task[A]): Env[E, A] = EnvTask(task) def delay[E, A](x: => A): Env[E, A] = later(x) def defer[E, A](x: => Env[E, A]): Env[E, A] = Env(ctx => Task.defer(x.run(ctx))) def deferTask[E, A](x: => Task[A]): Env[E, A] = fromTask(Task.defer(x)) def deferFuture[E, A](future: => Future[A]): Env[E, A] = EnvTask(Task.deferFuture(future)) def deferFutureContext[E, A](future: E => Future[A]): Env[E, A] = Env(ctx => Task.deferFuture(future(ctx))) def deferFutureAction[E, A](futAct: Scheduler => Future[A]): Env[E, A] = EnvTask(Task.deferFutureAction(futAct)) def raiseError[E, A](throwable: Throwable): Env[E, A] = EnvTask(Task.raiseError(throwable)) def attempt[E, A](e: Env[E, A]): Env[E, Either[Throwable, A]] = e.attempt def fromFunc[E, A](f: E => A): Env[E, A] = Env.withContextNow(f) def fromReaderT[E, A](reader: ReaderT[Task, E, A]): Env[E, A] = Env(reader.run) def fromTry[E, A](t: Try[A]): Env[E, A] = fromTask(Task.fromTry(t)) def fromEither[E, A](e: Either[Throwable, A]): Env[E, A] = fromTask(Task.fromTry(e.toTry)) def fromFuture[E, A](future: Future[A]): Env[E, A] = EnvTask(Task.fromFuture(future)) def fromTryFunc[E, A](ft: E => Try[A]): Env[E, A] = Env(ctx => Task.fromTry(ft(ctx))) def fromEffect[F[_]: Effect, E, A](fa: F[A]): Env[E, A] = fromTask(Task.fromEffect(fa)) def fromEffectFunc[F[_]: Effect, E, A](ffa: E => F[A]): Env[E, A] = Env(ctx => Task.fromEffect(ffa(ctx))) def fromEval[E, A](ea: Eval[A]): Env[E, A] = fromTask(Task.from(ea)) def fromEvalFunc[E, A](fea: E => Eval[A]): Env[E, A] = Env(ctx => Task.from(fea(ctx))) def fromIO[E, A](ioa: IO[A]): Env[E, A] = fromTask(Task.from(ioa)) def fromIOFunc[E, A](fioa: E => IO[A]): Env[E, A] = Env(ctx => Task.from(fioa(ctx))) def fromCoeval[E, A](ca: Coeval[A]): Env[E, A] = fromTask(ca.to[Task]) def fromCoevalFunc[E, A](fca: E => Coeval[A]): Env[E, A] = Env(ctx => fca(ctx).to[Task]) def tailRecM[E, A, B](a: A)(f: (A) => Env[E, Either[A, B]]): Env[E, B] = Env(ctx => Task.tailRecM(a)(a1 => f(a1).run(ctx))) def when[E](cond: => Boolean)(io: => Env[E, _]): Env[E, Unit] = whenF(delay[E, Boolean](cond))(io) def whenF[E](cond: Env[E, Boolean])(io: => Env[E, _]): Env[E, Unit] = cond.flatMap(run => if (run) io.flatMap(_ => Env.unit[E]) else Env.unit[E]) }
Example 79
Source File: MonixWebSocketHandler.scala From sttp with Apache License 2.0 | 5 votes |
package sttp.client.httpclient.monix import monix.eval.Task import monix.execution.Scheduler import sttp.client.httpclient.WebSocketHandler import sttp.client.httpclient.internal.NativeWebSocketHandler import sttp.client.impl.monix.{MonixAsyncQueue, TaskMonadAsyncError} import sttp.client.ws.{WebSocket, WebSocketEvent} object MonixWebSocketHandler { val IncomingBufferCapacity = 2 // has to be at least 2 (opening frame + one data frame) def apply()(implicit s: Scheduler ): Task[WebSocketHandler[WebSocket[Task]]] = { Task { val queue = new MonixAsyncQueue[WebSocketEvent](Some(IncomingBufferCapacity)) NativeWebSocketHandler(queue, TaskMonadAsyncError) } } }
Example 80
Source File: HttpClientMonixBackend.scala From sttp with Apache License 2.0 | 5 votes |
package sttp.client.httpclient.monix import java.io.InputStream import java.net.http.HttpRequest.BodyPublishers import java.net.http.{HttpClient, HttpRequest} import java.nio.ByteBuffer import cats.effect.Resource import monix.eval.Task import monix.execution.Scheduler import monix.reactive.Observable import org.reactivestreams.FlowAdapters import sttp.client.httpclient.HttpClientBackend.EncodingHandler import sttp.client.httpclient.{HttpClientAsyncBackend, HttpClientBackend, WebSocketHandler} import sttp.client.impl.monix.TaskMonadAsyncError import sttp.client.testing.SttpBackendStub import sttp.client.{FollowRedirectsBackend, SttpBackend, SttpBackendOptions} import scala.util.{Success, Try} class HttpClientMonixBackend private ( client: HttpClient, closeClient: Boolean, customizeRequest: HttpRequest => HttpRequest, customEncodingHandler: EncodingHandler )(implicit s: Scheduler) extends HttpClientAsyncBackend[Task, Observable[ByteBuffer]]( client, TaskMonadAsyncError, closeClient, customizeRequest, customEncodingHandler ) { override def streamToRequestBody(stream: Observable[ByteBuffer]): Task[HttpRequest.BodyPublisher] = { monad.eval(BodyPublishers.fromPublisher(FlowAdapters.toFlowPublisher(stream.toReactivePublisher))) } override def responseBodyToStream(responseBody: InputStream): Try[Observable[ByteBuffer]] = { Success( Observable .fromInputStream(Task.now(responseBody)) .map(ByteBuffer.wrap) .guaranteeCase(_ => Task(responseBody.close())) ) } } object HttpClientMonixBackend { private def apply( client: HttpClient, closeClient: Boolean, customizeRequest: HttpRequest => HttpRequest, customEncodingHandler: EncodingHandler )(implicit s: Scheduler ): SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler] = new FollowRedirectsBackend( new HttpClientMonixBackend(client, closeClient, customizeRequest, customEncodingHandler)(s) ) def apply( options: SttpBackendOptions = SttpBackendOptions.Default, customizeRequest: HttpRequest => HttpRequest = identity, customEncodingHandler: EncodingHandler = PartialFunction.empty )(implicit s: Scheduler = Scheduler.global ): Task[SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler]] = Task.eval( HttpClientMonixBackend( HttpClientBackend.defaultClient(options), closeClient = true, customizeRequest, customEncodingHandler )(s) ) def resource( options: SttpBackendOptions = SttpBackendOptions.Default, customizeRequest: HttpRequest => HttpRequest = identity, customEncodingHandler: EncodingHandler = PartialFunction.empty )(implicit s: Scheduler = Scheduler.global ): Resource[Task, SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler]] = Resource.make(apply(options, customizeRequest, customEncodingHandler))(_.close()) def usingClient( client: HttpClient, customizeRequest: HttpRequest => HttpRequest = identity, customEncodingHandler: EncodingHandler = PartialFunction.empty )(implicit s: Scheduler = Scheduler.global): SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler] = HttpClientMonixBackend(client, closeClient = false, customizeRequest, customEncodingHandler)(s) def stub: SttpBackendStub[Task, Observable[ByteBuffer], WebSocketHandler] = SttpBackendStub(TaskMonadAsyncError) }
Example 81
Source File: GrpcMonix.scala From grpcmonix with MIT License | 5 votes |
package grpcmonix import com.google.common.util.concurrent.ListenableFuture import io.grpc.stub.StreamObserver import monix.eval.{Callback, Task} import monix.execution.Ack.{Continue, Stop} import monix.execution.{Ack, Scheduler} import monix.reactive.Observable import monix.reactive.observables.ObservableLike.{Operator, Transformer} import monix.reactive.observers.Subscriber import monix.reactive.subjects.PublishSubject import org.reactivestreams.{Subscriber => SubscriberR} import scalapb.grpc.Grpc import scala.concurrent.Future object GrpcMonix { type GrpcOperator[I, O] = StreamObserver[O] => StreamObserver[I] def guavaFutureToMonixTask[T](future: ListenableFuture[T]): Task[T] = Task.deferFuture { Grpc.guavaFuture2ScalaFuture(future) } def grpcOperatorToMonixOperator[I,O](grpcOperator: GrpcOperator[I,O]): Operator[I,O] = { outputSubsriber: Subscriber[O] => val outputObserver: StreamObserver[O] = monixSubscriberToGrpcObserver(outputSubsriber) val inputObserver: StreamObserver[I] = grpcOperator(outputObserver) grpcObserverToMonixSubscriber(inputObserver, outputSubsriber.scheduler) } def monixSubscriberToGrpcObserver[T](subscriber: Subscriber[T]): StreamObserver[T] = new StreamObserver[T] { override def onError(t: Throwable): Unit = subscriber.onError(t) override def onCompleted(): Unit = subscriber.onComplete() override def onNext(value: T): Unit = subscriber.onNext(value) } def reactiveSubscriberToGrpcObserver[T](subscriber: SubscriberR[_ >: T]): StreamObserver[T] = new StreamObserver[T] { override def onError(t: Throwable): Unit = subscriber.onError(t) override def onCompleted(): Unit = subscriber.onComplete() override def onNext(value: T): Unit = subscriber.onNext(value) } def grpcObserverToMonixSubscriber[T](observer: StreamObserver[T], s: Scheduler): Subscriber[T] = new Subscriber[T] { override implicit def scheduler: Scheduler = s override def onError(t: Throwable): Unit = observer.onError(t) override def onComplete(): Unit = observer.onCompleted() override def onNext(value: T): Future[Ack] = try { observer.onNext(value) Continue } catch { case t: Throwable => observer.onError(t) Stop } } def grpcObserverToMonixCallback[T](observer: StreamObserver[T]): Callback[T] = new Callback[T] { override def onError(t: Throwable): Unit = observer.onError(t) override def onSuccess(value: T): Unit = { observer.onNext(value) observer.onCompleted() } } def liftByGrpcOperator[I, O](observable: Observable[I], operator: GrpcOperator[I, O]): Observable[O] = observable.liftByOperator( grpcOperatorToMonixOperator(operator) ) def unliftByTransformer[I, O](transformer: Transformer[I, O], subscriber: Subscriber[O]): Subscriber[I] = new Subscriber[I] { private[this] val subject = PublishSubject[I]() subject.transform(transformer).subscribe(subscriber) override implicit def scheduler: Scheduler = subscriber.scheduler override def onError(t: Throwable): Unit = subject.onError(t) override def onComplete(): Unit = subject.onComplete() override def onNext(value: I): Future[Ack] = subject.onNext(value) } }
Example 82
Source File: MigrateV12ToV13.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.{EventEnvelope, NoOffset, PersistenceQuery} import cats.implicits._ import ch.epfl.bluebrain.nexus.admin.client.AdminClient import ch.epfl.bluebrain.nexus.admin.client.types.Project import ch.epfl.bluebrain.nexus.commons.test.Resources import ch.epfl.bluebrain.nexus.iam.client.types._ import ch.epfl.bluebrain.nexus.kg.config.AppConfig import ch.epfl.bluebrain.nexus.kg.config.Vocabulary.nxv import ch.epfl.bluebrain.nexus.kg.resources.Event.{Created, Updated} import ch.epfl.bluebrain.nexus.kg.resources.{OrganizationRef, ResId, Views} import com.typesafe.scalalogging.Logger import io.circe.Json import io.circe.parser.parse import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import scala.concurrent.Future object MigrateV12ToV13 extends Resources { private val log = Logger[MigrateV12ToV13.type] private val newMapping = jsonContentOf("/elasticsearch/mapping.json") private val defaultEsId = nxv.defaultElasticSearchIndex.value private implicit val mockedAcls: AccessControlLists = AccessControlLists.empty def migrate( views: Views[Task], adminClient: AdminClient[Task] )(implicit config: AppConfig, as: ActorSystem, sc: Scheduler, pm: CanBlock): Unit = { implicit val token: Option[AuthToken] = config.iam.serviceAccountToken def checkAndUpdateMapping(id: ResId, rev: Long, source: Json)( implicit project: Project, caller: Caller ): Task[Unit] = { source.hcursor.get[String]("mapping").flatMap(parse) match { case Left(err) => log.error(s"Error while fetching mapping for view id ${id.show}. Reason: '$err'") Task.unit case Right(mapping) if mapping == newMapping => Task.unit case _ => views.update(id, rev, source deepMerge Json.obj("mapping" -> newMapping)).value.flatMap { case Left(err) => log.error(s"Error updating the view with id '${id.show}' and rev '$rev'. Reason: '$err'") Task.unit case _ => log.info(s"View with id '${id.show}' and rev '$rev' was successfully updated.") Task.unit } } } def fetchProject(orgRef: OrganizationRef, id: ResId)(f: Project => Task[Unit]): Task[Unit] = { adminClient.fetchProject(orgRef.id, id.parent.id).flatMap { case Some(project) => f(project) case None => log.error(s"Project with id '${id.parent.id}' was not found for view with id '${id.show}'") Task.unit } } log.info("Migrating views mappings.") val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) Task .fromFuture { pq.currentEventsByTag(s"type=${nxv.ElasticSearchView.value.asString}", NoOffset) .mapAsync(1) { case EventEnvelope(_, _, _, Created(id, orgRef, _, _, source, _, subject)) if id.value == defaultEsId => fetchProject(orgRef, id) { project => checkAndUpdateMapping(id, 1L, source)(project, Caller(subject, Set(subject))) }.runToFuture case EventEnvelope(_, _, _, Updated(id, orgRef, rev, _, source, _, subject)) if id.value == defaultEsId => fetchProject(orgRef, id) { project => checkAndUpdateMapping(id, rev, source)(project, Caller(subject, Set(subject))) }.runToFuture case _ => Future.unit } .runFold(0) { case (acc, _) => if (acc % 10 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .map(_ => ()) } .runSyncUnsafe() log.info("Finished migrating views mappings.") } }
Example 83
Source File: RepairFromMessages.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg import java.net.URLDecoder import java.util.UUID import akka.actor.ActorSystem import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal import akka.persistence.query.PersistenceQuery import ch.epfl.bluebrain.nexus.kg.resources.{Id, Repo, ResId} import ch.epfl.bluebrain.nexus.kg.resources.ProjectIdentifier.ProjectRef import ch.epfl.bluebrain.nexus.rdf.Iri import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import scala.concurrent.Future import scala.util.Try object RepairFromMessages { // $COVERAGE-OFF$ private val log = Logger[RepairFromMessages.type] def repair(repo: Repo[Task])(implicit as: ActorSystem, sc: Scheduler, pm: CanBlock): Unit = { log.info("Repairing dependent tables from messages.") val pq = PersistenceQuery(as).readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier) Task .fromFuture { pq.currentPersistenceIds() .mapAsync(1) { case ResourceId(id) => (repo.get(id, None).value >> Task.unit).runToFuture case other => log.warn(s"Unknown persistence id '$other'") Future.successful(()) } .runFold(0) { case (acc, _) => if (acc % 1000 == 0) log.info(s"Processed '$acc' persistence ids.") acc + 1 } .map(_ => ()) } .runSyncUnsafe() log.info("Finished repairing dependent tables from messages.") } object ResourceId { private val regex = "^resources\\-([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12})\\-(.+)$".r def unapply(arg: String): Option[ResId] = arg match { case regex(stringUuid, stringId) => for { uuid <- Try(UUID.fromString(stringUuid)).toOption iri <- Iri.absolute(URLDecoder.decode(stringId, "UTF-8")).toOption } yield Id(ProjectRef(uuid), iri) case _ => None } } // $COVERAGE-ON$ }
Example 84
Source File: GRPCServerExtension.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.grpc import java.net.InetSocketAddress import com.wavesplatform.extensions.{Extension, Context => ExtensionContext} import com.wavesplatform.settings.GRPCSettings import com.wavesplatform.utils.ScorexLogging import io.grpc.Server import io.grpc.netty.NettyServerBuilder import monix.execution.Scheduler import net.ceedubs.ficus.Ficus._ import net.ceedubs.ficus.readers.ArbitraryTypeReader._ import scala.concurrent.Future class GRPCServerExtension(context: ExtensionContext) extends Extension with ScorexLogging { @volatile var server: Server = _ override def start(): Unit = { val settings = context.settings.config.as[GRPCSettings]("waves.grpc") this.server = startServer(settings) } override def shutdown(): Future[Unit] = { log.debug("Shutting down gRPC server") if (server != null) { server.shutdown() Future(server.awaitTermination())(context.actorSystem.dispatcher) } else { Future.successful(()) } } private[this] def startServer(settings: GRPCSettings): Server = { implicit val apiScheduler: Scheduler = Scheduler(context.actorSystem.dispatcher) val bindAddress = new InetSocketAddress(settings.host, settings.port) val server: Server = NettyServerBuilder .forAddress(bindAddress) .addService(TransactionsApiGrpc.bindService(new TransactionsApiGrpcImpl(context.transactionsApi), apiScheduler)) .addService(BlocksApiGrpc.bindService(new BlocksApiGrpcImpl(context.blocksApi), apiScheduler)) .addService(AccountsApiGrpc.bindService(new AccountsApiGrpcImpl(context.accountsApi), apiScheduler)) .addService(AssetsApiGrpc.bindService(new AssetsApiGrpcImpl(context.assetsApi, context.accountsApi), apiScheduler)) .addService(BlockchainApiGrpc.bindService(new BlockchainApiGrpcImpl(context.blockchain, context.settings.featuresSettings), apiScheduler)) .build() .start() log.info(s"gRPC API was bound to $bindAddress") server } }
Example 85
Source File: AccountsApiGrpcImpl.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.grpc import com.google.protobuf.ByteString import com.google.protobuf.wrappers.{BytesValue, StringValue} import com.wavesplatform.account.{Address, Alias} import com.wavesplatform.api.common.CommonAccountsApi import com.wavesplatform.common.state.ByteStr import com.wavesplatform.protobuf.Amount import com.wavesplatform.protobuf.transaction.PBTransactions import com.wavesplatform.transaction.Asset import io.grpc.stub.StreamObserver import monix.execution.Scheduler import monix.reactive.Observable import scala.concurrent.Future class AccountsApiGrpcImpl(commonApi: CommonAccountsApi)(implicit sc: Scheduler) extends AccountsApiGrpc.AccountsApi { private def loadWavesBalance(address: Address): BalanceResponse = { val details = commonApi.balanceDetails(address) BalanceResponse().withWaves( BalanceResponse.WavesBalances( details.regular, details.generating, details.available, details.effective, details.leaseIn, details.leaseOut ) ) } private def assetBalanceResponse(v: (Asset.IssuedAsset, Long)): BalanceResponse = BalanceResponse().withAsset(Amount(v._1.id.toPBByteString, v._2)) override def getBalances(request: BalancesRequest, responseObserver: StreamObserver[BalanceResponse]): Unit = responseObserver.interceptErrors { val addressOption: Option[Address] = if (request.address.isEmpty) None else Some(request.address.toAddress) val assetIds: Seq[Asset] = request.assets.map(id => if (id.isEmpty) Asset.Waves else Asset.IssuedAsset(ByteStr(id.toByteArray))) val responseStream = (addressOption, assetIds) match { case (Some(address), Seq()) => Observable(loadWavesBalance(address)) ++ commonApi.portfolio(address).map(assetBalanceResponse) case (Some(address), nonEmptyList) => Observable .fromIterable(nonEmptyList) .map { case Asset.Waves => loadWavesBalance(address) case ia: Asset.IssuedAsset => assetBalanceResponse(ia -> commonApi.assetBalance(address, ia)) } case (None, Seq(_)) => // todo: asset distribution Observable.empty case (None, _) => // multiple distributions are not supported Observable.empty } responseObserver.completeWith(responseStream) } override def getScript(request: AccountRequest): Future[ScriptData] = Future { commonApi.script(request.address.toAddress) match { case Some(desc) => ScriptData(PBTransactions.toPBScript(Some(desc.script)), desc.script.expr.toString, desc.verifierComplexity) case None => ScriptData() } } override def getActiveLeases(request: AccountRequest, responseObserver: StreamObserver[TransactionResponse]): Unit = responseObserver.interceptErrors { val transactions = commonApi.activeLeases(request.address.toAddress) val result = transactions.map { case (height, transaction) => TransactionResponse(transaction.id(), height, Some(transaction.toPB)) } responseObserver.completeWith(result) } override def getDataEntries(request: DataRequest, responseObserver: StreamObserver[DataEntryResponse]): Unit = responseObserver.interceptErrors { val stream = if (request.key.nonEmpty) { Observable.fromIterable(commonApi.data(request.address.toAddress, request.key)) } else { commonApi.dataStream(request.address.toAddress, Option(request.key).filter(_.nonEmpty)) } responseObserver.completeWith(stream.map(de => DataEntryResponse(request.address, Some(PBTransactions.toPBDataEntry(de))))) } override def resolveAlias(request: StringValue): Future[BytesValue] = Future { val result = for { alias <- Alias.create(request.value) address <- commonApi.resolveAlias(alias) } yield BytesValue(ByteString.copyFrom(address.bytes)) result.explicitGetErr() } }
Example 86
Source File: AssetsApiGrpcImpl.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.grpc import com.wavesplatform.account.Address import com.wavesplatform.api.common.{CommonAccountsApi, CommonAssetsApi} import com.wavesplatform.api.http.ApiError.TransactionDoesNotExist import com.wavesplatform.common.state.ByteStr import com.wavesplatform.protobuf.transaction.PBTransactions import com.wavesplatform.state.AssetScriptInfo import com.wavesplatform.state.AssetDescription import com.wavesplatform.transaction.Asset.IssuedAsset import io.grpc.stub.StreamObserver import monix.execution.Scheduler import monix.reactive.Observable import scala.concurrent.Future class AssetsApiGrpcImpl(assetsApi: CommonAssetsApi, accountsApi: CommonAccountsApi)(implicit sc: Scheduler) extends AssetsApiGrpc.AssetsApi { override def getInfo(request: AssetRequest): Future[AssetInfoResponse] = Future { val result = for (info <- assetsApi.fullInfo(IssuedAsset(request.assetId))) yield { val result = assetInfoResponse(info.description).withSponsorBalance(info.sponsorBalance.getOrElse(0)) info.issueTransaction.map(_.toPB).fold(result)(result.withIssueTransaction) } result.explicitGetErr(TransactionDoesNotExist) } override def getNFTList(request: NFTRequest, responseObserver: StreamObserver[NFTResponse]): Unit = responseObserver.interceptErrors { val addressOption: Option[Address] = if (request.address.isEmpty) None else Some(request.address.toAddress) val afterAssetId: Option[IssuedAsset] = if (request.afterAssetId.isEmpty) None else Some(IssuedAsset(ByteStr(request.afterAssetId.toByteArray))) val responseStream = addressOption match { case Some(address) => accountsApi .nftList(address, afterAssetId) .map { case (a, d) => NFTResponse(a.id.toPBByteString, Some(assetInfoResponse(d))) } .take(request.limit) case _ => Observable.empty } responseObserver.completeWith(responseStream) } private def assetInfoResponse(d: AssetDescription): AssetInfoResponse = AssetInfoResponse( d.issuer, d.name.toStringUtf8, d.description.toStringUtf8, d.decimals, d.reissuable, d.totalVolume.longValue, d.script.map { case AssetScriptInfo(script, complexity) => ScriptData( PBTransactions.toPBScript(Some(script)), script.expr.toString, complexity ) }, d.sponsorship ) }
Example 87
Source File: BlockchainApiGrpcImpl.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.grpc import com.google.protobuf.ByteString import com.google.protobuf.empty.Empty import com.wavesplatform.features.{BlockchainFeatureStatus, BlockchainFeatures} import com.wavesplatform.settings.FeaturesSettings import com.wavesplatform.state.Blockchain import monix.execution.Scheduler import scala.concurrent.Future class BlockchainApiGrpcImpl(blockchain: Blockchain, featuresSettings: FeaturesSettings)(implicit sc: Scheduler) extends BlockchainApiGrpc.BlockchainApi { override def getActivationStatus(request: ActivationStatusRequest): Future[ActivationStatusResponse] = Future { val functionalitySettings = blockchain.settings.functionalitySettings ActivationStatusResponse( request.height, functionalitySettings.activationWindowSize(request.height), functionalitySettings.blocksForFeatureActivation(request.height), functionalitySettings.activationWindow(request.height).last, (blockchain.featureVotes(request.height).keySet ++ blockchain.approvedFeatures.keySet ++ BlockchainFeatures.implemented).toSeq.sorted.map(id => { val status = blockchain.featureStatus(id, request.height) match { case BlockchainFeatureStatus.Undefined => FeatureActivationStatus.BlockchainFeatureStatus.UNDEFINED case BlockchainFeatureStatus.Approved => FeatureActivationStatus.BlockchainFeatureStatus.APPROVED case BlockchainFeatureStatus.Activated => FeatureActivationStatus.BlockchainFeatureStatus.ACTIVATED } FeatureActivationStatus( id, BlockchainFeatures.feature(id).fold("Unknown feature")(_.description), status, (BlockchainFeatures.implemented.contains(id), featuresSettings.supported.contains(id)) match { case (false, _) => FeatureActivationStatus.NodeFeatureStatus.NOT_IMPLEMENTED case (_, true) => FeatureActivationStatus.NodeFeatureStatus.VOTED case _ => FeatureActivationStatus.NodeFeatureStatus.IMPLEMENTED }, blockchain.featureActivationHeight(id).getOrElse(0), if (status.isUndefined) blockchain.featureVotes(request.height).getOrElse(id, 0) else 0 ) }) ) } override def getBaseTarget(request: Empty): Future[BaseTargetResponse] = Future { BaseTargetResponse(blockchain.lastBlockHeader.get.header.baseTarget) } override def getCumulativeScore(request: Empty): Future[ScoreResponse] = Future { ScoreResponse(ByteString.copyFrom(blockchain.score.toByteArray)) } }
Example 88
Source File: BlocksApiGrpcImpl.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.grpc import com.google.protobuf.empty.Empty import com.google.protobuf.wrappers.UInt32Value import com.wavesplatform.api.BlockMeta import com.wavesplatform.api.common.CommonBlocksApi import com.wavesplatform.api.grpc.BlockRangeRequest.Filter import com.wavesplatform.api.grpc.BlockRequest.Request import com.wavesplatform.api.http.ApiError.BlockDoesNotExist import com.wavesplatform.protobuf.block.PBBlock import com.wavesplatform.transaction.Transaction import io.grpc.stub.StreamObserver import monix.execution.Scheduler import scala.concurrent.Future class BlocksApiGrpcImpl(commonApi: CommonBlocksApi)(implicit sc: Scheduler) extends BlocksApiGrpc.BlocksApi { import BlocksApiGrpcImpl._ override def getCurrentHeight(request: Empty): Future[UInt32Value] = { Future.successful(UInt32Value(commonApi.currentHeight)) } override def getBlockRange(request: BlockRangeRequest, responseObserver: StreamObserver[BlockWithHeight]): Unit = responseObserver.interceptErrors { val stream = if (request.includeTransactions) commonApi .blocksRange(request.fromHeight, request.toHeight) .map(toBlockWithHeight) else commonApi .metaRange(request.fromHeight, request.toHeight) .map { meta => BlockWithHeight(Some(PBBlock(Some(meta.header.toPBHeader), meta.signature)), meta.height) } responseObserver.completeWith(request.filter match { case Filter.GeneratorPublicKey(publicKey) => stream.filter(_.getBlock.getHeader.generator.toPublicKey == publicKey.toPublicKey) case Filter.GeneratorAddress(address) => stream.filter(_.getBlock.getHeader.generator.toAddress == address.toAddress) case Filter.Empty => stream }) } override def getBlock(request: BlockRequest): Future[BlockWithHeight] = Future { val result = request.request match { case Request.BlockId(blockId) => commonApi .block(blockId) .map(toBlockWithHeight) case Request.Height(height) => val actualHeight = if (height > 0) height else commonApi.currentHeight + height commonApi .blockAtHeight(actualHeight) .map(toBlockWithHeight) case Request.Empty => None } val finalResult = if (request.includeTransactions) result else result.map(_.update(_.block.transactions := Nil)) finalResult.explicitGetErr(BlockDoesNotExist) } } object BlocksApiGrpcImpl { private def toBlockWithHeight(v: (BlockMeta, Seq[(Transaction, Boolean)])) = { BlockWithHeight(Some(PBBlock(Some(v._1.header.toPBHeader), v._1.signature.toPBByteString, v._2.map(_._1.toPB))), v._1.height) } }
Example 89
Source File: Signed.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.transaction import com.wavesplatform.transaction.TxValidationError.InvalidSignature import monix.eval.{Coeval, Task} import monix.execution.Scheduler import monix.execution.schedulers.SchedulerService import scala.concurrent.Await import scala.concurrent.duration.Duration trait Signed extends Authorized { protected val signatureValid: Coeval[Boolean] protected val signedDescendants: Coeval[Seq[Signed]] = Coeval(Nil) protected val signaturesValidMemoized: Task[Either[InvalidSignature, this.type]] = Signed.validateTask[this.type](this).memoize val signaturesValid: Coeval[Either[InvalidSignature, this.type]] = Coeval.evalOnce(Await.result(signaturesValidMemoized.runToFuture(Signed.scheduler), Duration.Inf)) } object Signed { type E[A] = Either[InvalidSignature, A] private implicit lazy val scheduler: SchedulerService = { val parallelism = (Runtime.getRuntime.availableProcessors() / 2).max(1).min(4) Scheduler.computation(parallelism, "sig-validator") } def validateOrdered[S <: Signed](ss: Seq[S]): E[Seq[S]] = Await.result( Task .parTraverse(ss)(s => s.signaturesValidMemoized) .map( _.collectFirst { case Left(v) => Left(v) }.getOrElse(Right(ss)) ) .runAsyncLogErr, Duration.Inf ) private def validateTask[S <: Signed](signedEntity: S): Task[E[S]] = Task { import cats.instances.either._ import cats.instances.list._ import cats.syntax.traverse._ if (!signedEntity.signatureValid()) { Task.now(Left(InvalidSignature(signedEntity, None))) } else if (signedEntity.signedDescendants().isEmpty) { Task.now(Right(signedEntity)) } else { Task .parTraverseUnordered(signedEntity.signedDescendants())(s => s.signaturesValidMemoized) .map(_.sequence.map(_ => signedEntity)) } }.flatten }
Example 90
Source File: ChannelClosedHandler.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import io.netty.channel.ChannelHandler.Sharable import io.netty.channel._ import monix.execution.Scheduler import monix.reactive.Observable import monix.reactive.subjects.ConcurrentSubject @Sharable class ChannelClosedHandler private extends ChannelHandlerAdapter { private val closedChannelsSubject = ConcurrentSubject.publish[Channel](Scheduler.global) override def handlerAdded(ctx: ChannelHandlerContext): Unit = { ctx.channel().closeFuture().addListener((cf: ChannelFuture) => closedChannelsSubject.onNext(cf.channel())) super.handlerAdded(ctx) } def shutdown(): Unit = { closedChannelsSubject.onComplete() } } object ChannelClosedHandler { def apply(): (ChannelClosedHandler, Observable[Channel]) = { val h = new ChannelClosedHandler() (h, h.closedChannelsSubject) } }
Example 91
Source File: CustomDirectives.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.http import akka.http.scaladsl.server.{Directive1, _} import com.wavesplatform.http.ApiMarshallers import com.wavesplatform.utils.ScorexLogging import monix.execution.{Scheduler, UncaughtExceptionReporter} import play.api.libs.json.JsObject trait CustomDirectives extends Directives with ApiMarshallers with ScorexLogging { def anyParam(paramName: String): Directive1[Iterable[String]] = (get & parameter(paramName.as[String].*).map(_.toSeq.reverse)) | post & (formField(paramName.as[String].*) | entity(as[JsObject]).map { jso => (jso \ s"${paramName}s").as[Iterable[String]] }) def extractScheduler: Directive1[Scheduler] = extractExecutionContext.map(ec => Scheduler(ec, UncaughtExceptionReporter((t: Throwable) => log.debug("Error processing request", t)))) }
Example 92
Source File: TimeLimitedRoute.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.api.http import akka.http.scaladsl.marshalling.ToResponseMarshallable import akka.http.scaladsl.server.{Directive1, ExceptionHandler, Route} import com.google.common.util.concurrent.{ExecutionError, UncheckedExecutionException} import com.wavesplatform.utils.Schedulers import monix.execution.Scheduler import scala.concurrent.ExecutionException trait TimeLimitedRoute { self: ApiRoute => def limitedScheduler: Scheduler def executeLimited[T](f: => T): Directive1[T] = { val handler = ExceptionHandler { case _: InterruptedException | _: ExecutionException | _: ExecutionError | _: UncheckedExecutionException => complete(ApiError.CustomValidationError("The request took too long to complete")) } handleExceptions(handler) & onSuccess(Schedulers.executeCatchingInterruptedException(limitedScheduler)(f)) } def completeLimited(f: => ToResponseMarshallable): Route = executeLimited(f)(complete(_)) }
Example 93
Source File: ScorexLogging.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.utils import monix.eval.Task import monix.execution.{CancelableFuture, Scheduler} import monix.reactive.Observable import org.slf4j.{Logger, LoggerFactory} case class LoggerFacade(logger: Logger) { def trace(message: => String, throwable: Throwable): Unit = { if (logger.isTraceEnabled) logger.trace(message, throwable) } def trace(message: => String): Unit = { if (logger.isTraceEnabled) logger.trace(message) } def debug(message: => String, arg: Any): Unit = { if (logger.isDebugEnabled) logger.debug(message, arg) } def debug(message: => String): Unit = { if (logger.isDebugEnabled) logger.debug(message) } def info(message: => String): Unit = { if (logger.isInfoEnabled) logger.info(message) } def info(message: => String, arg: Any): Unit = { if (logger.isInfoEnabled) logger.info(message, arg) } def info(message: => String, throwable: Throwable): Unit = { if (logger.isInfoEnabled) logger.info(message, throwable) } def warn(message: => String): Unit = { if (logger.isWarnEnabled) logger.warn(message) } def warn(message: => String, throwable: Throwable): Unit = { if (logger.isWarnEnabled) logger.warn(message, throwable) } def error(message: => String): Unit = { if (logger.isErrorEnabled) logger.error(message) } def error(message: => String, throwable: Throwable): Unit = { if (logger.isErrorEnabled) logger.error(message, throwable) } } trait ScorexLogging { protected lazy val log = LoggerFacade(LoggerFactory.getLogger(this.getClass)) implicit class TaskExt[A](t: Task[A]) { def runAsyncLogErr(implicit s: Scheduler): CancelableFuture[A] = logErr.runToFuture(s) def logErr: Task[A] = { t.onErrorHandleWith(ex => { log.error(s"Error executing task", ex) Task.raiseError[A](ex) }) } } implicit class ObservableExt[A](o: Observable[A]) { def logErr: Observable[A] = { o.onErrorHandleWith(ex => { log.error(s"Error observing item", ex) Observable.raiseError[A](ex) }) } } }
Example 94
Source File: MicroblockAppender.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.state.appender import cats.data.EitherT import com.wavesplatform.block.Block.BlockId import com.wavesplatform.block.MicroBlock import com.wavesplatform.lang.ValidationError import com.wavesplatform.metrics.{BlockStats, _} import com.wavesplatform.network.MicroBlockSynchronizer.MicroblockData import com.wavesplatform.network._ import com.wavesplatform.state.Blockchain import com.wavesplatform.transaction.BlockchainUpdater import com.wavesplatform.transaction.TxValidationError.InvalidSignature import com.wavesplatform.utils.ScorexLogging import com.wavesplatform.utx.UtxPool import io.netty.channel.Channel import io.netty.channel.group.ChannelGroup import kamon.Kamon import monix.eval.Task import monix.execution.Scheduler import scala.util.{Left, Right} object MicroblockAppender extends ScorexLogging { def apply(blockchainUpdater: BlockchainUpdater with Blockchain, utxStorage: UtxPool, scheduler: Scheduler, verify: Boolean = true)( microBlock: MicroBlock ): Task[Either[ValidationError, BlockId]] = { Task(metrics.microblockProcessingTimeStats.measureSuccessful { blockchainUpdater .processMicroBlock(microBlock, verify) .map { totalBlockId => utxStorage.removeAll(microBlock.transactionData) totalBlockId } }).executeOn(scheduler) } def apply( blockchainUpdater: BlockchainUpdater with Blockchain, utxStorage: UtxPool, allChannels: ChannelGroup, peerDatabase: PeerDatabase, scheduler: Scheduler )(ch: Channel, md: MicroblockData): Task[Unit] = { import md.microBlock val microblockTotalResBlockSig = microBlock.totalResBlockSig (for { _ <- EitherT(Task.now(microBlock.signaturesValid())) _ <- EitherT(apply(blockchainUpdater, utxStorage, scheduler)(microBlock)) } yield ()).value.map { case Right(_) => md.invOpt match { case Some(mi) => allChannels.broadcast(mi, except = md.microblockOwners()) case None => log.warn(s"${id(ch)} Not broadcasting MicroBlockInv") } BlockStats.applied(microBlock) case Left(is: InvalidSignature) => peerDatabase.blacklistAndClose(ch, s"Could not append microblock $microblockTotalResBlockSig: $is") case Left(ve) => BlockStats.declined(microBlock) log.debug(s"${id(ch)} Could not append microblock $microblockTotalResBlockSig: $ve") } } private[this] object metrics { val microblockProcessingTimeStats = Kamon.timer("microblock-appender.processing-time").withoutTags() } }
Example 95
Source File: RxScheduler.scala From Waves with MIT License | 5 votes |
package com.wavesplatform import com.wavesplatform.account.KeyPair import com.wavesplatform.block.{Block, MicroBlock} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.crypto._ import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.transfer._ import monix.execution.schedulers.SchedulerService import monix.execution.{Ack, Scheduler} import monix.reactive.Observer import org.scalatest.{BeforeAndAfterAll, Suite} import scala.concurrent.duration._ import scala.concurrent.{Await, Future} trait RxScheduler extends BeforeAndAfterAll { _: Suite => implicit val implicitScheduler: SchedulerService = Scheduler.singleThread("rx-scheduler") def testSchedulerName: String lazy val testScheduler: SchedulerService = Scheduler.singleThread(testSchedulerName) def test[A](f: => Future[A]): A = Await.result(f, 10.seconds) def send[A](p: Observer[A])(a: A): Future[Ack] = p.onNext(a) .map(ack => { Thread.sleep(500) ack }) def byteStr(id: Int): ByteStr = ByteStr(Array.concat(Array.fill(SignatureLength - 1)(0), Array(id.toByte))) val signer: KeyPair = TestBlock.defaultSigner def block(id: Int): Block = TestBlock.create(Seq.empty).copy(signature = byteStr(id)) def microBlock(total: Int, prev: Int): MicroBlock = { val tx = TransferTransaction.selfSigned(1.toByte, signer, signer.toAddress, Waves, 1, Waves, 1, ByteStr.empty, 1).explicitGet() MicroBlock.buildAndSign(3.toByte, signer, Seq(tx), byteStr(prev), byteStr(total)).explicitGet() } override protected def afterAll(): Unit = { super.afterAll() implicitScheduler.shutdown() testScheduler.shutdown() } }
Example 96
Source File: MicroBlockMinerSpec.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.mining import com.wavesplatform.account.Alias import com.wavesplatform.block.Block import com.wavesplatform.common.utils._ import com.wavesplatform.db.WithDomain import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.mining.microblocks.MicroBlockMinerImpl import com.wavesplatform.mining.microblocks.MicroBlockMinerImpl.MicroBlockMiningResult import com.wavesplatform.settings.TestFunctionalitySettings import com.wavesplatform.transaction.{CreateAliasTransaction, GenesisTransaction, TxVersion} import com.wavesplatform.utils.Schedulers import com.wavesplatform.utx.UtxPoolImpl import com.wavesplatform.{TestValues, TransactionGen} import monix.eval.Task import monix.execution.Scheduler import org.scalamock.scalatest.PathMockFactory import org.scalatest.{FlatSpec, Matchers, PrivateMethodTester} import scala.concurrent.duration._ import scala.util.Random class MicroBlockMinerSpec extends FlatSpec with Matchers with PrivateMethodTester with PathMockFactory with WithDomain with TransactionGen { "Micro block miner" should "generate microblocks in flat interval" in { val scheduler = Schedulers.singleThread("test") val acc = TestValues.keyPair val genesis = GenesisTransaction.create(acc.toAddress, TestValues.bigMoney, TestValues.timestamp).explicitGet() val settings = domainSettingsWithFS(TestFunctionalitySettings.withFeatures(BlockchainFeatures.NG)) withDomain(settings) { d => d.appendBlock(TestBlock.create(Seq(genesis))) val utxPool = new UtxPoolImpl(ntpTime, d.blockchainUpdater, ignoreSpendableBalanceChanged, settings.utxSettings, enablePriorityPool = true) val microBlockMiner = new MicroBlockMinerImpl( _ => (), null, d.blockchainUpdater, utxPool, settings.minerSettings, scheduler, scheduler ) val generateOneMicroBlockTask = PrivateMethod[Task[MicroBlockMiningResult]](Symbol("generateOneMicroBlockTask")) def generateBlocks( block: Block, constraint: MiningConstraint, lastMicroBlock: Long ): Block = { val task = microBlockMiner invokePrivate generateOneMicroBlockTask( acc, block, MiningConstraints(d.blockchainUpdater, d.blockchainUpdater.height, Some(settings.minerSettings)), constraint, lastMicroBlock ) import Scheduler.Implicits.global val startTime = System.nanoTime() val tx = CreateAliasTransaction .selfSigned(TxVersion.V1, acc, Alias.create("test" + Random.nextInt()).explicitGet(), TestValues.fee, TestValues.timestamp) .explicitGet() utxPool.putIfNew(tx).resultE.explicitGet() val result = task.runSyncUnsafe() result match { case res @ MicroBlockMinerImpl.Success(b, totalConstraint) => val isFirstBlock = block.transactionData.isEmpty val elapsed = (res.nanoTime - startTime).nanos.toMillis if (isFirstBlock) elapsed should be < 1000L else elapsed shouldBe settings.minerSettings.microBlockInterval.toMillis +- 1000 generateBlocks(b, totalConstraint, res.nanoTime) case MicroBlockMinerImpl.Stop => d.blockchainUpdater.liquidBlock(d.blockchainUpdater.lastBlockId.get).get case MicroBlockMinerImpl.Retry => throw new IllegalStateException() } } val baseBlock = Block .buildAndSign( 3, TestValues.timestamp, d.lastBlockId, d.lastBlock.header.baseTarget, d.lastBlock.header.generationSignature, Nil, acc, Nil, 0 ) .explicitGet() d.appendBlock(baseBlock) val constraint = OneDimensionalMiningConstraint(5, TxEstimators.one, "limit") val lastBlock = generateBlocks(baseBlock, constraint, 0) lastBlock.transactionData should have size constraint.rest.toInt } } }
Example 97
Source File: EnvRouting.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.finagle.envRouting import cats.syntax.semigroup._ import com.twitter import com.twitter.finagle.http.{Request, Response, Status} import com.twitter.finagle.{Service, http} import com.twitter.util.{Future, Promise} import monix.eval.Task import monix.execution.Scheduler import ru.tinkoff.tschema.finagle.Rejection.Recover import ru.tinkoff.tschema.finagle._ import ru.tinkoff.tschema.finagle.envRouting.EnvRouting.EnvHttp import ru.tinkoff.tschema.utils.SubString import tofu.env.Env final case class EnvRouting[+R]( request: http.Request, path: CharSequence, matched: Int, embedded: R ) object EnvRouting extends EnvInstanceDecl { type EnvHttp[R, +A] = Env[EnvRouting[R], A] implicit def taskRouted[R] : RoutedPlus[EnvHttp[R, *]] with ConvertService[EnvHttp[R, *]] with LiftHttp[EnvHttp[R, *], Env[R, *]] = envRoutedAny.asInstanceOf[EnvRoutedConvert[R]] implicit def envRunnable[R](implicit recover: Recover[EnvHttp[R, *]] = Recover.default[EnvHttp[R, *]] ): RunHttp[EnvHttp[R, *], Env[R, *]] = response => { val handled = response.onErrorRecoverWith { case Rejected(rej) => recover(rej) } Env(r => Task.deferAction(implicit sched => Task.delay(execResponse(r, handled, _)))) } private[this] def execResponse[R](r: R, envResponse: EnvHttp[R, Response], request: Request)(implicit sc: Scheduler ): Future[Response] = { val promise = Promise[Response] val routing = EnvRouting(request, SubString(request.path), 0, r) val cancelable = envResponse.run(routing).runAsync { case Right(res) => promise.setValue(res) case Left(ex) => val resp = Response(Status.InternalServerError) val message = Option(ex.getLocalizedMessage).getOrElse(ex.toString) resp.setContentString(message) promise.setValue(resp) } promise.setInterruptHandler { case _ => cancelable.cancel() } promise } } private[finagle] class EnvInstanceDecl { protected trait EnvRoutedConvert[R] extends RoutedPlus[EnvHttp[R, *]] with ConvertService[EnvHttp[R, *]] with LiftHttp[EnvHttp[R, *], Env[R, *]] { private type F[a] = EnvHttp[R, a] implicit private[this] val self: RoutedPlus[F] = this def matched: F[Int] = Env.fromFunc(_.matched) def withMatched[A](m: Int, fa: F[A]): F[A] = fa.local(_.copy(matched = m)) def path: F[CharSequence] = Env.fromFunc(_.path) def request: F[http.Request] = Env.fromFunc(_.request) def reject[A](rejection: Rejection): F[A] = Routed.unmatchedPath[F].flatMap(path => throwRej(rejection withPath path.toString)) def combineK[A](x: F[A], y: F[A]): F[A] = catchRej(x)(xrs => catchRej(y)(yrs => throwRej(xrs |+| yrs))) def convertService[A](svc: Service[http.Request, A]): F[A] = Env { r => Task.cancelable { cb => val fut = svc(r.request).respond { case twitter.util.Return(a) => cb.onSuccess(a) case twitter.util.Throw(ex) => cb.onError(ex) } Task(fut.raise(new InterruptedException)) } } def apply[A](fa: Env[R, A]): EnvHttp[R, A] = fa.localP(_.embedded) @inline private[this] def catchRej[A](z: F[A])(f: Rejection => F[A]): F[A] = z.onErrorRecoverWith { case Rejected(xrs) => f(xrs) } @inline private[this] def throwRej[A](map: Rejection): F[A] = Env.raiseError(envRouting.Rejected(map)) } protected object envRoutedAny extends EnvRoutedConvert[Any] }
Example 98
Source File: TaskRouting.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.finagle.envRouting import cats.syntax.semigroup._ import com.twitter import com.twitter.finagle.http.{Request, Response, Status} import com.twitter.finagle.{Service, http} import com.twitter.util.{Future, Promise} import monix.eval.Task import monix.execution.Scheduler import ru.tinkoff.tschema.finagle.Rejection.Recover import ru.tinkoff.tschema.finagle._ import ru.tinkoff.tschema.finagle.envRouting.TaskRouting.TaskHttp import ru.tinkoff.tschema.utils.SubString import tofu.env.Env final case class TaskRouting( request: http.Request, path: CharSequence, matched: Int ) object TaskRouting extends TaskInstanceDecl { type TaskHttp[+A] = Env[TaskRouting, A] implicit val taskRouted: RoutedPlus[TaskHttp] with ConvertService[TaskHttp] with LiftHttp[TaskHttp, Task] = new TaskRoutedConvert implicit def envRunnable(implicit recover: Recover[TaskHttp] = Recover.default[TaskHttp] ): RunHttp[TaskHttp, Task] = response => Task.deferAction(implicit sched => Task.delay(execResponse(response, _))) private[this] def execResponse( envResponse: TaskHttp[Response], request: Request )(implicit sc: Scheduler, recover: Recover[TaskHttp]): Future[Response] = { val promise = Promise[Response] val routing = TaskRouting(request, SubString(request.path), 0) val cancelable = envResponse.onErrorRecoverWith { case Rejected(rej) => recover(rej) }.run(routing).runAsync { case Right(res) => promise.setValue(res) case Left(ex) => val resp = Response(Status.InternalServerError) resp.setContentString(ex.getMessage) promise.setValue(resp) } promise.setInterruptHandler { case _ => cancelable.cancel() } promise } } private[finagle] class TaskInstanceDecl { protected class TaskRoutedConvert extends RoutedPlus[TaskHttp] with ConvertService[TaskHttp] with LiftHttp[TaskHttp, Task] { private type F[a] = TaskHttp[a] implicit private[this] val self: RoutedPlus[F] = this def matched: F[Int] = Env.fromFunc(_.matched) def withMatched[A](m: Int, fa: F[A]): F[A] = fa.local(_.copy(matched = m)) def path: F[CharSequence] = Env.fromFunc(_.path) def request: F[http.Request] = Env.fromFunc(_.request) def reject[A](rejection: Rejection): F[A] = Routed.unmatchedPath[F].flatMap(path => throwRej(rejection withPath path.toString)) def combineK[A](x: F[A], y: F[A]): F[A] = catchRej(x)(xrs => catchRej(y)(yrs => throwRej(xrs |+| yrs))) def convertService[A](svc: Service[http.Request, A]): F[A] = Env { r => Task.cancelable { cb => val fut = svc(r.request).respond { case twitter.util.Return(a) => cb.onSuccess(a) case twitter.util.Throw(ex) => cb.onError(ex) } Task(fut.raise(new InterruptedException)) } } def apply[A](fa: Task[A]): TaskHttp[A] = Env.fromTask(fa) @inline private[this] def catchRej[A](z: F[A])(f: Rejection => F[A]): F[A] = z.onErrorRecoverWith { case Rejected(xrs) => f(xrs) } @inline private[this] def throwRej[A](map: Rejection): F[A] = Env.raiseError(envRouting.Rejected(map)) } }
Example 99
Source File: MonixTest.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.test import java.util.concurrent.Executors import monix.execution.Scheduler import monix.reactive.Observable import org.scalatest.AsyncWordSpec import ru.tinkoff.phobos.annotations.{ElementCodec, XmlCodec} import ru.tinkoff.phobos.decoding.XmlDecoder import ru.tinkoff.phobos.syntax.text import ru.tinkoff.phobos.monix._ class MonixTest extends AsyncWordSpec { implicit val scheduler: Scheduler = Scheduler(Executors.newScheduledThreadPool(4)) "Monix decoder" should { "decode case classes correctly" in { @ElementCodec case class Bar(@text txt: Int) @XmlCodec("foo") case class Foo(qux: Int, maybeBar: Option[Bar], bars: List[Bar]) val xml = """ |<foo> | <qux>1234</qux> | <bars>2</bars> | <maybeBar>1</maybeBar> | <bars>3</bars> |</foo> |""".stripMargin val foo = Foo(1234, Some(Bar(1)), List(Bar(2), Bar(3))) val observable = Observable.fromIterable(xml.toIterable.map(x => Array(x.toByte))) XmlDecoder[Foo] .decodeFromObservable(observable) .map(result => assert(result == foo)) .runToFuture } } }
Example 100
Source File: MultiPartBody.scala From RosHTTP with MIT License | 5 votes |
package fr.hmil.roshttp.body import java.nio.ByteBuffer import monix.execution.Scheduler import monix.reactive.Observable import scala.util.Random class MultiPartBody(parts: Map[String, BodyPart], subtype: String = "form-data")(implicit scheduler: Scheduler) extends BodyPart { val boundary = "----" + Random.alphanumeric.take(24).mkString.toLowerCase override def contentType: String = s"multipart/$subtype; boundary=$boundary" override def content: Observable[ByteBuffer] = { parts. // Prepend multipart encapsulation boundary and body part headers to // each body part. map({ case (name, part) => ByteBuffer.wrap( ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"" + name + "\"\r\n" + s"Content-Type: ${part.contentType}\r\n" + "\r\n").getBytes("utf-8") ) +: part.content }). // Join body parts reduceLeft((acc, elem) => acc ++ elem). // Append the closing boundary :+(ByteBuffer.wrap(s"\r\n--$boundary--\r\n".getBytes("utf-8"))) } } object MultiPartBody { def apply(parts: (String, BodyPart)*)(implicit scheduler: Scheduler): MultiPartBody = new MultiPartBody(Map(parts: _*)) }
Example 101
Source File: SimpleHttpResponse.scala From RosHTTP with MIT License | 5 votes |
package fr.hmil.roshttp.response import java.nio.ByteBuffer import fr.hmil.roshttp.BackendConfig import fr.hmil.roshttp.exceptions.ResponseException import fr.hmil.roshttp.util.{HeaderMap, Utils} import monix.execution.Scheduler import monix.reactive.Observable import scala.collection.mutable import scala.concurrent.{Future, Promise} import scala.util.{Failure, Success} class SimpleHttpResponse( val statusCode: Int, val headers: HeaderMap[String], val body: String) extends HttpResponse object SimpleHttpResponse extends HttpResponseFactory[SimpleHttpResponse] { override def apply( header: HttpResponseHeader, bodyStream: Observable[ByteBuffer], config: BackendConfig) (implicit scheduler: Scheduler): Future[SimpleHttpResponse] = { val charset = Utils.charsetFromContentType(header.headers.getOrElse("content-type", null)) val buffers = mutable.Queue[ByteBuffer]() val promise = Promise[SimpleHttpResponse]() val streamCollector = bodyStream. foreach(elem => buffers.enqueue(elem)). map({_ => val body = recomposeBody(buffers, config.maxChunkSize, charset) new SimpleHttpResponse(header.statusCode, header.headers, body) }) streamCollector.onComplete({ case res:Success[SimpleHttpResponse] => promise.trySuccess(res.value) case e:Failure[_] => promise.tryFailure(new ResponseException(e.exception, header)) }) promise.future } private def recomposeBody(seq: mutable.Queue[ByteBuffer], maxChunkSize: Int, charset: String): String = { // Allocate maximum expected body length val buffer = ByteBuffer.allocate(seq.length * maxChunkSize) val totalBytes = seq.foldLeft(0)({ (count, chunk) => buffer.put(chunk) count + chunk.limit() }) buffer.limit(totalBytes) Utils.getStringFromBuffer(buffer, charset) } }
Example 102
Source File: StreamHttpResponse.scala From RosHTTP with MIT License | 5 votes |
package fr.hmil.roshttp.response import java.nio.ByteBuffer import fr.hmil.roshttp.BackendConfig import fr.hmil.roshttp.util.HeaderMap import monix.execution.Scheduler import monix.reactive.Observable import scala.concurrent.Future class StreamHttpResponse( val statusCode: Int, val headers: HeaderMap[String], val body: Observable[ByteBuffer]) extends HttpResponse object StreamHttpResponse extends HttpResponseFactory[StreamHttpResponse] { override def apply( header: HttpResponseHeader, bodyStream: Observable[ByteBuffer], config: BackendConfig) (implicit scheduler: Scheduler): Future[StreamHttpResponse] = Future.successful(new StreamHttpResponse(header.statusCode, header.headers, bodyStream)) }
Example 103
Source File: HttpDriver.scala From RosHTTP with MIT License | 5 votes |
package fr.hmil.roshttp import fr.hmil.roshttp.node.Modules.{HttpModule, HttpsModule} import fr.hmil.roshttp.response.{HttpResponse, HttpResponseFactory} import monix.execution.Scheduler import scala.concurrent.Future private object HttpDriver extends DriverTrait { private var _driver: Option[DriverTrait] = None def send[T <: HttpResponse](req: HttpRequest, factory: HttpResponseFactory[T])(implicit scheduler: Scheduler): Future[T] = { _driver.getOrElse(chooseBackend()).send(req, factory) } private def chooseBackend(): DriverTrait = { if (HttpModule.isAvailable && HttpsModule.isAvailable) { _driver = Some(NodeDriver) } else { _driver = Some(BrowserDriver) } _driver.get } }
Example 104
Source File: KnownBossesMap.scala From gbf-raidfinder with MIT License | 3 votes |
package walfie.gbf.raidfinder import akka.agent.Agent import java.util.Date import monix.execution.{Ack, Cancelable, Scheduler} import monix.reactive._ import monix.reactive.subjects.ConcurrentSubject import scala.concurrent.{ExecutionContext, Future} import walfie.gbf.raidfinder.domain._ trait KnownBossesMap { def get(): Map[BossName, RaidBoss] def newBossObservable(): Observable[RaidBoss] class KnownBossesObserver( initialBosses: Seq[RaidBoss] )(implicit scheduler: Scheduler) extends Observer[RaidInfo] with KnownBossesMap { private val agent = Agent[Map[BossName, RaidBoss]]( initialBosses.map(boss => boss.name -> boss)(scala.collection.breakOut) ) // TODO: Write test for this private val subject = ConcurrentSubject.publish[RaidBoss] val newBossObservable: Observable[RaidBoss] = subject def onComplete(): Unit = () def onError(e: Throwable): Unit = () def onNext(elem: RaidInfo): Future[Ack] = { val name = elem.tweet.bossName val raidBoss = elem.boss if (!agent.get.isDefinedAt(name)) { subject.onNext(raidBoss) } agent.alter(_.updated(name, raidBoss)).flatMap(_ => Ack.Continue) } def get(): Map[BossName, RaidBoss] = agent.get() def purgeOldBosses( minDate: Date, levelThreshold: Option[Int] ): Future[Map[BossName, RaidBoss]] = { agent.alter(_.filter { case (name, boss) => boss.lastSeen.after(minDate) || levelThreshold.exists(boss.level >= _) }) } }