<commit_before>## Tranquility

Tranquility helps you send event streams to Druid, the raddest data store ever (http://druid.io/), in real-time. It
handles partitioning, replication, service discovery, and schema rollover for you, seamlessly and without downtime.
Tranquility is written in Scala, and bundles idiomatic Java and Scala APIs that work nicely with Finagle, Storm, and
Trident.

This project is a friend of Druid. For discussion, feel free to use the normal Druid channels: http://druid.io/community.html

## Finagle

For general purposes, you'll likely end up using the Finagle API. You can set up and use a Finagle Service like this:

```scala
val indexService = "druid:overlord" // Your overlord's service name.
val firehosePattern = "druid:firehose:%s" // Make up a service pattern, include %s somewhere in it.
val discoveryPath = "/discovery" // Your overlord's druid.discovery.curator.path
val dataSource = "foo"
val dimensions = Seq("bar")
val aggregators = Seq(new LongSumAggregatorFactory("baz", "baz"))

val druidService = DruidBeams
  .builder((eventMap: Map[String, Any]) => new DateTime(eventMap("timestamp")))
  .curator(curator)
  .discoveryPath(discoveryPath)
  .location(DruidLocation(new DruidEnvironment(indexService, firehosePattern), dataSource))
  .rollup(DruidRollup(SpecificDruidDimensions(dimensions), aggregators, QueryGranularity.MINUTE))
  .tuning(ClusteredBeamTuning(Granularity.HOUR, 10.minutes, 1, 1))
  .buildService()

// Send events to Druid:
val numSentFuture: Future[Int] = druidService(listOfEvents)<commit_msg>Clarify API choices.<commit_after>## Tranquility

Tranquility helps you send event streams to Druid, the raddest data store ever (http://druid.io/), in real-time. It
handles partitioning, replication, service discovery, and schema rollover for you, seamlessly and without downtime.
Tranquility is written in Scala, and bundles idiomatic Java and Scala APIs that work nicely with Finagle, Storm, and
Trident.

This project is a friend of Druid. For discussion, feel free to use the normal Druid channels: http://druid.io/community.html

## Direct API

If you want to write a program that sends data to Druid, you'll likely end up using the direct Finagle-based API. (The other alternative is the Storm API, described in the next section.)

You can set up and use a Finagle Service like this:

```scala
val indexService = "druid:overlord" // Your overlord's service name.
val firehosePattern = "druid:firehose:%s" // Make up a service pattern, include %s somewhere in it.
val discoveryPath = "/discovery" // Your overlord's druid.discovery.curator.path
val dataSource = "foo"
val dimensions = Seq("bar")
val aggregators = Seq(new LongSumAggregatorFactory("baz", "baz"))

val druidService = DruidBeams
  .builder((eventMap: Map[String, Any]) => new DateTime(eventMap("timestamp")))
  .curator(curator)
  .discoveryPath(discoveryPath)
  .location(DruidLocation(new DruidEnvironment(indexService, firehosePattern), dataSource))
  .rollup(DruidRollup(SpecificDruidDimensions(dimensions), aggregators, QueryGranularity.MINUTE))
  .tuning(ClusteredBeamTuning(Granularity.HOUR, 10.minutes, 1, 1))
  .buildService()

// Send events to Druid:
val numSentFuture: Future[Int] = druidService(listOfEvents)
{'fraction_non_alphanumeric': 0.09723076923076923, 'fraction_numerical': 0.0024615384615384616, 'mean_word_length': 5.502, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4371759', 'n_tokens_mistral': 1011, 'n_tokens_neox': 979, 'n_words': 348}