Skip to content

Commit

Permalink
Merge pull request #1 from LisiLisenok/develop
Browse files Browse the repository at this point in the history
0.1.0 prelim
  • Loading branch information
LisiLisenok committed Mar 13, 2016
2 parents 47b073d + ef368bd commit cd28788
Show file tree
Hide file tree
Showing 36 changed files with 3,365 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="source"/>
<classpathentry kind="src" path="examples"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="com.redhat.ceylon.eclipse.ui.cpcontainer.RUNTIME_CONTAINER/default"/>
<classpathentry kind="con" path="com.redhat.ceylon.eclipse.ui.cpcontainer.CEYLON_CONTAINER/default"/>
<classpathentry kind="output" path="classes"/>
</classpath>
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/.exploded/
27 changes: 27 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Chime</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.redhat.ceylon.eclipse.ui.ceylonBuilder</name>
<arguments>
<dictionary>
<key>systemRepo</key>
<value></value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.redhat.ceylon.eclipse.ui.ceylonNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
# Chime
Time scheduler for Vert.x
## Chime

_Chime_ is time scheduler which works on _Vert.x_ event bus and provides:

* scheduling with _cron-style_ and _interval_ timers
* applying time zones available on _JVM_

>Runs with Ceylon 1.2.0 and Vert.x 3.2.1

## Dependences

* ceylon.language/1.2.0
* ceylon.time/1.2.0
* io.vertx.ceylon.core/3.2.1


## Documentation


4 changes: 4 additions & 0 deletions examples/herd/examples/schedule/chime/module.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
native("jvm")
module herd.examples.schedule.chime "0.1.0" {
shared import io.vertx.ceylon.core "3.2.1";
}
1 change: 1 addition & 0 deletions examples/herd/examples/schedule/chime/package.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shared package herd.examples.schedule.chime;
111 changes: 111 additions & 0 deletions examples/herd/examples/schedule/chime/run.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import io.vertx.ceylon.core.eventbus {

EventBus,
Message
}
import ceylon.json {

JSON=Object
}
import io.vertx.ceylon.core {

Vertx,
vertx
}


"Runs the module `herd.examples.schedule.chime`."
shared void run() {
value v = vertx.vertx();
v.deployVerticle (
"ceylon:herd.schedule.chime/0.1.0",
( String|Throwable res ) {
if ( is String res ) {
value scheduler = Scheduler( v );
scheduler.initialize();
}
else {
print( "deploying error ``res``");
}
}
);
}


"Performs scheduler run. Creates cron-style timer and listens it.
"
class Scheduler( Vertx v, String address = "chime" )
{
EventBus eventBus = v.eventBus();


"Initializes testing - creates schedule manager and timer."
shared void initialize() {
eventBus.send<JSON> (
address,
JSON {
"operation" -> "create",
"name" -> "schedule manager",
"state" -> "running"
},
( Throwable | Message<JSON> msg ) {
if ( is Message<JSON> msg ) {
managerCreated( msg );
}
else {
print( "error in onConnect ``msg``" );
v.close();
}
}
);
}


void printMessage( Throwable | Message<JSON> msg ) {
if ( is Message<JSON> msg ) {
if ( exists body = msg.body() ) {
print( body );
if ( is String state = body.get( "state" ), state == "completed" ) {
v.close();
}
}
else {
print( "no body in the message" );
v.close();
}
}
else {
print( "error: ``msg``" );
}
}


void managerCreated( Message<JSON> msg ) {

eventBus.consumer( "schedule manager:timer", printMessage );

eventBus.send<JSON>(
address,
JSON {
"operation" -> "create",
"name" -> "schedule manager:timer",
"state" -> "running",
"publish" -> false,
"max count" -> 3,
"time zone" -> "Europe/Paris",
"descirption" -> JSON {
"type" -> "cron",
"seconds" -> "27/30",
"minutes" -> "*",
"hours" -> "0-23",
"days of month" -> "1-31",
"months" -> "*",
"days of week" -> "*",
"years" -> "2015-2019"
}
},
printMessage
);
}

}
70 changes: 70 additions & 0 deletions source/herd/schedule/chime/ChimeScheduler.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import io.vertx.ceylon.core {

Verticle
}
import ceylon.json {

JSON = Object
}
import herd.schedule.chime.timer {

definitions,
TimerFactory,
StandardTimerFactory
}


"Chime scheduler verticle. Starts scheduling."
by( "Lis" )
shared class ChimeScheduler() extends Verticle()
{

"Scheduler manager."
variable SchedulerManager? scheduler = null;

"Address to listen on event buss."
variable String address = definitions.defaultAddress;

"Max year limitation."
variable Integer maxYearPeriod = 10;

"Tolerance to compare fire time and current time in milliseconds."
variable Integer tolerance = 10;

"Factory to create timers - refine to produce timers of nonstandard types.
Standard factory creates cron-like timer and interval timer."
TimerFactory timerFactory = StandardTimerFactory( maxYearPeriod ).initialize();


"Reads configuration from json."
void readConfiguration( "Configuration in JSON format." JSON config ) {
// read listening address
if ( is String addr = config.get( definitions.address ) ) {
address = addr;
}
// year period limitation
if ( is Integer maxYear = config.get ( definitions.maxYearPeriodLimit ) ) {
if ( maxYear < 100 ) { maxYearPeriod = maxYear; }
else { maxYearPeriod = 100; }
}
// tolerance to compare times
if ( is Integer tol = config.get ( definitions.tolerance ) ) {
if ( tol > 0 ) { tolerance = tol; }
}
}


"Starts _Chime_. Called by Vert.x during deployement."
shared actual void start() {
// read configuration
if ( exists c = config ) {
readConfiguration( c );
}

// create scheduler
SchedulerManager sch = SchedulerManager( vertx, vertx.eventBus(), timerFactory, tolerance );
scheduler = sch;
sch.connect( address );
}

}
98 changes: 98 additions & 0 deletions source/herd/schedule/chime/Operator.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import ceylon.json {

JSON=Object
}
import io.vertx.ceylon.core.eventbus {

Message,
EventBus
}
import herd.schedule.chime.timer {
definitions
}


"Provides basic operations with [[JSON]] message."
see( `class SchedulerManager`, `class TimeScheduler` )
by( "Lis" )
abstract class Operator( "EventBus to pass messages." shared EventBus eventBus )
{

"Operators map."
variable Map<String, Anything(Message<JSON>)>? operators = null;

"creates operators map."
shared formal Map<String, Anything(Message<JSON>)> createOperators();


"Returns operator by operation code."
shared Anything(Message<JSON>)? getOperator( "operation code" String code ) {
if ( !operators exists ) {
// create operators map if doesn't exists
operators = createOperators();
}
return operators?.get( code );
}

"Responds on message.
respond format:
{
response -> String // response code
error -> String // error description
name -> String // item name
state -> String // item state
description -> JSON // item description
}
"
shared void respondMessage( "Message to respond on." Message<JSON> msg, "Rreply to be send" JSON reply ) {
reply.put( definitions.fieldResponse, definitions.responseOK );
msg.reply( reply );
}

"Fails message with message."
shared void failMessage (
"Message to be responded with failure." Message<JSON> msg,
"Error to fail with." String errorMessage )
{
msg.reply (
JSON {
definitions.fieldResponse -> definitions.responseError,
definitions.fieldError -> errorMessage
}
);
}

"Extracts state from request, helper method."
shared TimerState? extractState( JSON request ) {
if ( is String state = request.get( definitions.fieldState ) ) {
return timerRunning.byName( state );
}
else {
return null;
}
}

"Message has been received from event bus - process it!."
void onMessage( "Message from event bus." Message<JSON> msg ) {
if ( exists request = msg.body(), is String operation = request.get( definitions.fieldOperation ) ) {
// depending on operation code
if ( exists operator = getOperator( operation ) ) {
operator( msg );
}
else {
failMessage( msg, errorMessages.unsupportedOperation );
}
}
else {
// response with wrong format error
failMessage( msg, errorMessages.operationIsNotSpecified );
}
}

"Connects to event bus, returns promise resolved when event listener registered."
shared default void connect( "Address to listen to." String address ) {
// setup event bus listener
eventBus.consumer( address, onMessage );
}

}
Loading

0 comments on commit cd28788

Please sign in to comment.