Mixin for scalar object providing implicit and explicit conversions between
Java and Scala Ignite components.
It is very important to review this class as it defines what implicit conversions
will take place when using Scalar. Note that object scalar mixes in this
trait and therefore brings with it all implicits into the scope.
Contains Scala side adapters for implicits conversion.
Contains Scala "Pimp" implementations for main Ignite entities.
________ ______ ______ _______
__ ___/_____________ ____ /______ _________ __/__ \ __ __ \
_____ \ _ ___/_ __ `/__ / _ __ `/__ ___/ ____/ / _ / / /
____/ / / /__ / /_/ / _ / / /_/ / _ / _ __/___/ /_/ /
/____/ \___/ \__,_/ /_/ \__,_/ /_/ /____/_(_)____/
scalar is the main object that encapsulates Scalar DSL. It includes global functions
on "scalar" keyword, helper converters as well as necessary implicit conversions. scalar also
mimics many methods in Ignite class from Java side.
The idea behind Scalar DSL - zero additional logic and only conversions implemented
using Scala "Pimp" pattern. Note that most of the Scalar DSL development happened on Java
side of Ignite 3.0 product line - Java APIs had to be adjusted quite significantly to
support natural adaptation of functional APIs. That basically means that all functional
logic must be available on Java side and Scalar only provides conversions from Scala
language constructs to Java constructs. Note that currently Ignite supports Scala 2.8
and up only.
This design approach ensures that Java side does not starve and usage paradigm
is mostly the same between Java and Scala - yet with full power of Scala behind.
In other words, Scalar only adds Scala specifics, but not greatly altering semantics
of how Ignite APIs work. Most of the time the code in Scalar can be written in
Java in almost the same number of lines.
Symbol $ is used in names when they conflict with the names in the base Java class
that Scala pimp is shadowing or with Java package name that your Scala code is importing.
Instead of giving two different names to the same function we've decided to simply mark
Scala's side method with $ suffix.
Scalar needs to be imported in a proper way so that necessary objects and implicit
conversions got available in the scope:
Here are few short examples of how Scalar can be used to program routine distributed
task. All examples below use default Ignite configuration and default grid. All these
examples take an implicit advantage of auto-discovery and failover, load balancing and
collision resolution, zero deployment and many other underlying technologies in the
Ignite - while remaining absolutely distilled to the core domain logic.
This code snippet prints out full topology:
grid$ foreach (n => println("Node: " + n.id8))
grid$ *< (SPREAD, (for (w <- "Hello World!".split(" ")) yield () => println(w)))
grid$ *< (BROADCAST, () => println("Broadcasting!!!"))
val me = grid$.localNode.id
grid$.remoteProjection() *< (BROADCAST, F.println("Greetings from: " + me))
Next example creates a function that calculates lengths of the string
using MapReduce type of processing by splitting the input string into
multiple substrings, calculating each substring length on the remote
node and aggregating results for the final length of the original string:
def count(msg: String) =
grid$ @< (SPREAD, for (w <- msg.split(" ")) yield () => w.length, (s: Seq[Int]) => s.sum)
val t = cache$[Symbol, Double]("partitioned")
t += ('symbol -> 2.0)
t -= ('symbol)