Skip to content

Scala とか Play の Future と ExecutionContext について

Scala とか Play の Future と ExecutionContext について published on Scala とか Play の Future と ExecutionContext について へのコメントはまだありません

背景

Scala や Play! framework で Future 使うときに、ExecutionContext を渡せと言われる。よく分からない場合は、とりあえず

import scala.concurrent.ExecutionContext.Implicits.global

とやっておけば、とりあえずコンパイルは通るんだけど、よく分からずにやっている人も多いと思う(ノ)。

今回は、そっから先の話。

Continue reading Scala とか Play の Future と ExecutionContext について

Scala の並列コレクションが直列でしか動かないと思ったら・・・

Scala の並列コレクションが直列でしか動かないと思ったら・・・ published on Scala の並列コレクションが直列でしか動かないと思ったら・・・ へのコメントはまだありません

追記

やっぱり、並列コレクションを使うのはやめて、Future 使って、Execution Context とかをちゃんと設定する方法にした。

が、一応、以下の内容はそのまま残しておく。

並列コレクションを使う動機

今、いろんな API からデータを取ってきて、それらを検索可能にするっていう(元々は自分用の)サービスをちょこちょこ作っている。(興味のある方は以下のリンクより使ってみて、是非フィードバックを下さいませ↓)

Track Down Anything on GitHub, Slack or Google Drive | Commet

いろんな API からデータを取ってくるので、直列で実行すると、どっか1箇所の API が不調だったりしてレスポンスが遅いと、それに引きずられてしまうので、並列化しようと思った。

コード

元々のコードは、大雑把にはこんな感じ。

SomeDatabase.findAllApiEndpointsToCall.foreach { apiCall =>
  apiCall.execute
}

これを並列化しようとして、以下のコードにした。

# par をつけた
SomeDatabase.findAllApiEndpointsToCall.par.foreach { apiCall =>
  apiCall.execute
}

ログをみると、

02:08:35.008 [ForkJoinPool-3-worker-5] INFO xxxxx

という感じで、別スレッドで動くようになったようだけど、スレッド名が常に同じ=1つのスレッドしか使われていないらしい。

以下のドキュメントを見ると、設定変更出来るらしいので、やってみた。

Parallel Collections – Configuring Parallel Collections – Scala Documentation

val apiCalls = SomeDatabase.findAllApiEndpointsToCall.par

# TaskSupport なるものを作成して、コレクションのプロパティにセット
val taskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(4)) # 4並列
apiCalls.tasksupport = taskSupport

apiCalls.foreach { apiCall =>
  apiCall.execute
}

これで、とりあえず並列で処理されるようになった。

Continue reading Scala の並列コレクションが直列でしか動かないと思ったら・・・

Java (Scala) で言語判定

Java (Scala) で言語判定 published on Java (Scala) で言語判定 へのコメントはまだありません

やりたい事

  • Java (Scala) で、ある文字列が何語(日本語、英語、など)なのかを判別する
  • 入力文字列は以下の2通り
    • ユーザーから入力された検索文字列(1単語、数文字〜数単語、数十文字)
    • 検索対象となる文章(数十単語〜数十ページ程度)
  • 対応する言語
    • 当初は日本語と英語
    • 今後は5言語程度

なぜこれをやりたいかは、以下のエントリーを参照。

Elasticsearch多言語化その2 – K blog

Continue reading Java (Scala) で言語判定

Play! frameworkのJsPath.readNullableの挙動

Play! frameworkのJsPath.readNullableの挙動 published on Play! frameworkのJsPath.readNullableの挙動 へのコメントはまだありません

はじめに

Play! framework の JSON ライブラリって、慣れればまぁ普通に使えるけど、ドキュメントがイマイチだし、やりたいことをどう書けばいいかが分からなくて時間を使うことが多い。

今回書くのは、JSONデータである要素が存在しない場合にそれをどう扱うか、という話題。

「なんだ readNullable 使うだけでしょ?」

と思う人もいるかもしれない。まぁ実際にはそうなんだけど、readNullable の挙動が若干分かりにくかったので、それについて。

やりたいこと

JSONデータで、ある要素が存在する場合と存在しない場合が考えられるとき、その要素が存在する場合は Some 、存在しない場合は None としてパースしたい。

具体的な例で説明すると、Facebook APIから以下のようなJSONが返ってくるとする。内容はあるFacebookグループへの書き込み。

Continue reading Play! frameworkのJsPath.readNullableの挙動

Comparing nullable columns in Squeryl

Comparing nullable columns in Squeryl published on Comparing nullable columns in Squeryl へのコメントはまだありません

How to compare nullable columns in Squeryl

Suppose we have a table definition like this:

case class T1 (
  id: Int,
  col1: Option[Int]
)
object FooDb extends Schema {
  val t1 = table[T1]("t1")
}

And, we want to execute a query like the following:

select * from t1 where col1 < 10

The correct statement in Squeryl is shown below:

from(FooDb.t1)( t1 =>
  where(t1.col1 lt Some(10))
  select(t1)
)

This isn’t very intuitive, and actually, it took me a lot of time to get to this answer.

Here are some that I tried and failed

The most intuitive one doesn’t compile:

  where(t1.col1 lt 10) // -> doesn't compile

This one causes NoSuchElementException:

  where(t1.col1.get lt 10) // -> NoSuchElementException

Another one that causes NoSuchElementException:

  where(t1.col1.map(_ lt 10).get) // -> NoSuchElementException

Official site should have example

I’ve found some guys that were having the same issue:

I think the Squeryl web site should have an example that uses nullable column in the where clause.

Scala や Play! framework で DI

Scala や Play! framework で DI published on Scala や Play! framework で DI へのコメントはまだありません

自分用メモ

 

sbtでstacktraceを全部表示させる

sbtでstacktraceを全部表示させる published on sbtでstacktraceを全部表示させる への2件のコメント

自分用メモ。

Play! frameworkを使った開発で、エラー発生時にstacktraceが途中で途切れてしまう事がある、

ScalaTestの場合は、こちらにあるように以下のように指定する。

testOptions in Test += Tests.Argument("-oD")

sbt自身の話だが、デフォルトでは大抵のstack traceは隠されてしまう。

By default, sbt hides the stack trace of most exceptions thrown during execution. It prints a message that indicates how to display the exception. However, you may want to show more of stack traces by default.

表示するためには以下のようにする。詳しくはマニュアル参照。

> set every traceLevel := 0

最初からonにしててくれればいいのに。

追記:

xuwei_kさんからのコメントの通り、lastとやると、最後に実行したコマンドに関するログが出力される。マニュアルの一番上に書いてある。

When a command is run, more detailed logging output is sent to a file than to the screen (by default). This output can be recalled for the command just executed by running last.

ScalaのFutureがブロックする?(深く調べてない)

ScalaのFutureがブロックする?(深く調べてない) published on ScalaのFutureがブロックする?(深く調べてない) への3件のコメント

ScalaのFutureで(あるいはPlay?)で処理がブロックされてしまう現象があった。

環境

  • Scala 2.10.1
  • Play 2.1.3
  • (Playのモデルクラスを使っているだけで、scalaコマンドから起動されるバッチ処理)

簡略化するとこんなコード(実際はもっと分割されてるし、whileじゃなくてtailrecだけど)。

import scala.concurrent.Await
import scala.concurrent.duration._
import play.api.libs.concurrent.Execution.Implicits._
 
for {
  photo <- listOfPhotos
} yield {
  // downloadはサードパーティライブラリのメソッドで
  // Future[java.io.File]を返す
  val fut = photo.download map { file =>
    Logger.debug("start!") //ここまでは実行される。
    // SomeApi.postFileの挙動は、responseが返るまでブロックする。
    // しかし、↓が実行されない
    SomeApi.postFile(file) map { jobId =>
      var complete = false
      var result = None
      while (!complete) {
        Thread.sleep(5000)
        val job = SomeApi.getJob(jobId)
        if (job.isComplete()) {
          complete = true
          result = job.getResult()
          // resultに対して処理
        }
      }
    }
  }
  try {
    Await.result(fut, 120 seconds)
  } catch {
    case e: Exception => Logger.error(e.getMessage())
  }
}

Continue reading ScalaのFutureがブロックする?(深く調べてない)

Play! framework 2.xでJSONを扱う方法をいくつか

Play! framework 2.xでJSONを扱う方法をいくつか published on Play! framework 2.xでJSONを扱う方法をいくつか へのコメントはまだありません

Webサイト作ってると、JSONを扱うことが多い。なので、Play! frameworkで、ScalaのオブジェクトからJSON文字列に、あるいはその逆をやりたいよね、と(特に前者)。

そんな今回はObject -> JSONの方法をいくつかまとめてみた。

環境は Play 2.1.1。そのうち2.2にアップグレードしようと思うけど。

ちなみに Scala Advent Calendar 2013 の 12日目の記事ですら。

Continue reading Play! framework 2.xでJSONを扱う方法をいくつか

Lift CSS SelectorとAjax

Lift CSS SelectorとAjax published on Lift CSS SelectorとAjax へのコメントはまだありません

相変わらずボチボチLiftを触ってる。Lift 2.2 M1から入った便利な機能として、CSS Selectorがある。詳しくはWikiの該当のエントリを見てもらうとして、それとAjaxを組み合わせる方法。

■環境

Lift 2.2

■やりたい事

<form>タグを使った例はSimply Liftの4.8に載っているんだけど、普通のボタン(ajaxButton)を使いたかった。

DBのテーブルよりデータを取得して、HTMLの表にして出力。各行についているボタンをクリックすると、その行のデータに対する何らかの処理が行われるようにしたい。

結論から言うと簡単。

Continue reading Lift CSS SelectorとAjax