BEA Logo BEA WebLogic Server Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

Using WebLogic Time Services

I. Introduction
Overview of WebLogic Time services
WebLogic Time architecture

II. The API
WebLogic Time API reference
Overview of the WebLogic Time API

III. Implementing with WebLogic Time
Scheduling a recurring trigger on a T3Client
Scheduling a recurring server-side trigger from a T3Client
Step 1. Implement the ScheduleDef and TriggerDef interfaces
Step 2. Create the ScheduledTrigger from a T3Client
Setting up complex schedules
Rescheduling
Stopping a ScheduledTrigger

IV. Change history

Other related documents
Installing WebLogic (non-Windows)
Installing WebLogic (Windows)
Writing a T3Client application
Developers Guides
API Reference Manual
Code examples
Glossary

Overview of WebLogic Time

The WebLogic Time API provides a mechanism for scheduling actions (triggers) to take place at a future date and time, or on a regularly recurring schedule. WebLogic Time is an integrated service, one of the services offered with WebLogic for building distributed applications.

The Time API allows any user-written trigger to be scheduled and then executed, either in the client's JVM, or on the WebLogic Server on behalf of a client. Within the WebLogic framework, the Time API provides a dependable, distributable method of setting up actions that occur automatically. Note that WebLogic triggers are not real time triggers that can be used to millisecond granularity. WebLogic triggers used properly will function reliably within an estimated 1 second of accuracy.

Top

WebLogic Time architecture

WebLogic Time is one of the many integrated services provided in the WebLogic framework. Its API depends upon the communications and infrastructure that WebLogic provides, and it is designed as a lightweight, efficient API that shares many characteristics with other APIs in WebLogic's framework.

WebLogic Time is built around a ScheduledTriggerDef object, which is constructed from a Schedulable object, which takes care of starting, stopping, or repeating the schedule of action, and a Triggerable object, which defines the action to be carried out on schedule. Just as with other WebLogic services, you use an object factory rather than a constructor to create a ScheduledTrigger. Object factories provide a well-defined, easy-to-use methodology for managing scarce resources within the WebLogic framework.

The accounting for scheduling is kept in a series of efficient linked lists that are sorted only at the most proximate chronological point as new triggers are scheduled and then acted upon. For example, scheduling a trigger for a week from Tuesday at 12:15:30 is initially inserted simply into the schedule for next Tuesday. Not until noon on Tuesday is the schedule for the noon hour sorted, and not until fifteen minutes past noon are the triggers for that minute sorted. This drastically reduces the overhead for scheduling in a heavily scheduled environment.

WebLogic also keeps accounting of the differences in time zone, clock accuracy, and latency between users of the Time service, according to algorithms published in RFC 2030, Section 5.

Top

WebLogic Time API Reference

Package weblogic.time.common

The WebLogic Time public API is contained in a single package, weblogic.time.common.

Class java.lang.Object
   Class weblogic.common.internal.RemoteEntryPoint
      (implements weblogic.common.WLSerializable)
      Class weblogic.time.common.Scheduler
      Class weblogic.time.common.Trigger
   Interface weblogic.time.common.Schedulable
   Interface weblogic.time.common.ScheduleDef
      (extends weblogic.time.common.Schedulable)
   Interface weblogic.time.common.ScheduledTriggerDef
   Class java.lang.Throwable
(implements java.io.Serializable)
      Class java.lang.Exception
          Class weblogic.common.T3Exception
	      Class weblogic.time.common.TimeTriggerException
   Class weblogic.time.common.TimeRepeat
      (implements weblogic.time.common.Schedulable)
   Interface weblogic.time.common.TimeServicesDef
   Interface weblogic.time.common.TriggerDef
      (extends weblogic.time.common.Triggerable)
   Interface weblogic.time.common.Triggerable

Top

Overview of the WebLogic Time API

In general, the API for WebLogic Time is very similar to other service APIs in the WebLogic framework. You can use the Time API in client-side apps or server-side plugins. Using the Time API from within a T3Client application provides all of the infrastructure that comes with a T3Client, like Workspaces, logging, and access to other WebLogic Services.

Like other WebLogic APIs, the Time API uses an object factory to request ScheduledTrigger objects, which is central to the API. The object factory is called via the "services" stub at runtime, which references how WebLogic services are accessed.

The ScheduledTrigger takes two objects in its constructor:

  • An object that implements either the weblogic.time.common.Schedulable or the weblogic.time.common.ScheduleDef interface

  • An object that implements either the weblogic.time.common.Triggerable or the weblogic.time.common.TriggerDef interface.

The objects passed to the ScheduledTrigger object factory method may also be a client-side object, in which case the T3Client will create, schedule, and execute a ScheduledTrigger within its own VM. The client-side object must implement Schedulable (or ScheduleDef) and Triggerable (or TriggerDef).

The TimeServicesDef interface also provides methods for obtaining time-related information about client and server:

  • currentTimeMillis() returns the current server time, in "local server time" format, which is the server's time adjusted for propagation delay between the method invoker and the server (zero when the method invoker is the server, and some positive milliseconds when the invoker is the client or another WebLogic Server). This method uses the algorithm described in the overview, which conforms to RFC 2030, Section 5.

  • getRoundTripDelayMillis() returns the number of milliseconds of roundtrip delay between the client and server. This method depends on the algorithm described in the overview.

  • getLocalClockOffsetMillis() returns the number of milliseconds of offset between the client and server clocks, based on the algorithm described in the overview.

Provided in this package is also a class, weblogic.time.common.TimeRepeat, that implements Schedulable. This utility class is a prefabricated scheduler with which you can easily set up a repetitive trigger. Just pass an int that is the interval (in milliseconds) at which the trigger should be repeated. Then call its schedule() method with the starting time.

The package contains a single exception class, TimeTriggerException.

Top

Implementing with WebLogic Time

Scheduling a recurring trigger on a T3Client

Scheduling a recurring server-side trigger from a T3Client
Step 1. Implement the ScheduleDef and TriggerDef interfaces
Step 2. Create the ScheduledTrigger from a T3Client

Setting up complex schedules
Rescheduling
Stopping a ScheduledTrigger

Scheduling a recurring trigger on the client

The simplest case of scheduling a recurring trigger is to create a ScheduledTrigger that is scheduled and executed on a T3Client. In such a case, you write a class that implements both Schedulable and Triggerable, and then you implement the methods in those interfaces. Here is the class statement for an example that we'll use to illustrate how to schedule and execute a trigger:

import weblogic.time.common.*;
import weblogic.common.*;
import java.util.*;

class myTrigger implements Schedulable, Triggerable {
  ...
}

First, request a ScheduledTrigger object from the time services factory, and then call the schedule() and cancel() methods on the trigger, as shown in this example:

  public myTrigger() throws TimeTriggerException {
    // Create a T3Client
    T3Client t3 = new T3Client("t3://localhost:7001");
    t3.connect();

    // Request a ScheduledTrigger from the factory. Use
    // this class for scheduling and execution
    ScheduledTriggerDef std =
      t3.services.time().getScheduledTrigger(this, this);
    // Start the ball rolling
    std.schedule();
    // Your class may do other things after scheduling the trigger
    // When you are finished, cancel the trigger
    std.cancel();
  }
Now you will implement the methods in these interfaces.

The Schedulable interface has only one method, schedule(), which allows you to set the time at which the trigger should be executed.

The Triggerable interface has only one method, trigger(). (Note that this method signature will be changed in Release 3.1 so that you can pass a Schedulable object to the trigger() method. This will allow the same trigger to service multiple schedules.)

The trigger() method is where the work of the trigger takes place. (Please read the release note about this method.)

  public long schedule(long time) {
    // Schedule the trigger for every 5 seconds
    return time + 5000;
  }

  public void trigger() {
    // The trigger method is where the work takes place
    // This might be very complex, or simple as in this example
    System.out.println("trigger called");
  }

This example is self-contained within a single class that is both the scheduler and the trigger -- that is, the two arguments required to manufacture the ScheduledTrigger object are the the same client-side object, and the scheduler and trigger will both have access to any class variables necessary for trigger scheduling or execution. That means that the Schedulable and Triggerable objects do not require initialization parameters and do not need access to server-side WebLogic services. The Schedulable and Triggerable interfaces are very simple interfaces designed for convenience when you know a priori that the scheduler and the trigger will be instantiated and run in the same JVM.

Top

Scheduling a recurring server-side trigger from a T3Client

You can write more flexible schedulers and triggers, those that may be executed anywhere within the WebLogic framework, by implementing ScheduleDef instead of the simpler interface Schedulable, and TriggerDef instead of the simpler interface Triggerable. (ScheduleDef itself implements Schedulable, and TriggerDef itself implements Triggerable.) This example illustrates a more flexible implementation that uses a T3Client to create a recurring trigger that is subsequently scheduled and executed on a WebLogic Server (or anywhere within the WebLogic framework).

Here are the steps to creating a scheduled trigger in this scenario. You will need to write a class that implements ScheduleDef and TriggerDef -- and you may implement both in a single class, or in separate classes (for the sake of thoroughness, we implement these interfaces in separate classes in this example). Compile those classes and place them in your WebLogic Server host's classpath. Then you will create a ScheduledTrigger with those classes from a T3Client.

Step 1. Implement the ScheduleDef and TriggerDef interfaces

In this example, the scheduler implements ScheduleDef rather than Schedulable so that its setServices() and scheduleInit() methods will be called. The trigger implements TriggerDef rather than Triggerable for the same reason. These objects differ from the interfaces they themselves implement only in that they can be initialized with a ParamSet, and can get access to WebLogic services through the "services" stub. Here is why those two differences are important.

The setServices() method is used generically in all of the T3Client service-related interfaces to pass in a T3ServicesDef object -- the "services" reference -- at runtime. The T3ServicesDef object is implemented in various ways internally in the WebLogic framework, depending on where the object is instantiated. Because the T3ServicesDef object is set at runtime from within the WebLogic framework, you do not need to write different versions for client-side and server-side deployment; that's set quite transparently for you at runtime by WebLogic, when your class is dynamically instantiated.

When you instantiate an object dynamically, however, the classloader prevents the passing of parameters to its constructor. Consequently, all service-related interfaces -- including the Time interfaces -- require that you implement a scheduleInit() method that takes a ParamSet, so that you can pass initialization parameters for the object.

Here is a simple implementation of ScheduleDef.

package examples.time;

import weblogic.common.*;
import weblogic.time.common.*;
import java.util.*;

class MyScheduler implements ScheduleDef {

  private int interval = 0;
  private T3ServicesDef services;

  public void setServices(T3ServicesDef services) {
    this.services = services;
  }

  public void scheduleInit (ParamSet ps) throws ParamSetException {
    interval = ps.getParam("interval").asInt();
  }

  public long schedule(long currentMillis) {
    return currentMillis + interval;
  }
}

Here is a simple class that implements TriggerDef. In this case, we do not need to set or get any parameters for the Trigger, so we implement the method to do nothing.

package examples.time;

import weblogic.common.*;
import weblogic.time.common.*;
import java.util.*;

public class MyTrigger implements TriggerDef {

  private T3ServicesDef services;

  public void setServices(T3ServicesDef services) {
    this.services = services;
  }

  public void triggerInit (ParamSet ps) throws ParamSetException {}

  public void trigger(Schedulable sched) {
    System.out.println("trigger called");
  }
}

You could write a single class to implement both ScheduleDef and TriggerDef.

Step 2. Create the ScheduledTrigger from a T3Client

This method of setting up a scheduler and trigger require that you create a Scheduler and Trigger object to pass to the getScheduledTrigger() factory method. We created those in Step 1: MyScheduler and MyTrigger.

We have compiled those classes and placed them in the CLASSPATH of the WebLogic Server. Now we'll write a T3Client that uses those classes to schedule a trigger that runs in the server's JVM.

We use a ParamSet to pass initialization parameters between the instigating T3Client and the objects that the WebLogic Server instantiates. The class that we wrote in Step 1 to implement ScheduleDef depends upon a Parameter "interval" to be set by the caller, so we'll create a ParamSet with one Param. The class we wrote to implement TriggerDef doesn't require any initialization parameters.

  T3Client t3 = new T3Client("t3://localhost:7001");
  t3.connect();

  // Create a ParamSet to pass initialization parameters for
  // the ScheduleDef object. Set one parameter, "interval,"
  // for 10 seconds
  ParamSet schedParams = new ParamSet();
  schedParams.setParam("interval", 10000);

Now we'll create the Scheduler and Trigger wrapper objects that we'll use to instantiate a ScheduledTrigger on the server. The Scheduler and Trigger wrapper objects hold the name of the target class and a ParamSet to initialize it, if necessary.

  Scheduler scheduler =
    new Scheduler("examples.time.MyScheduler", schedParams);
  Trigger    trigger =
    new Trigger("examples.time.MyTrigger");

Finally, we use the time services object factory to manufacture a ScheduledTrigger. It takes two arguments, a Scheduler and a Trigger, which we have just created.

  ScheduledTriggerDef std =
    t3.services.time().getScheduledTrigger(scheduler, trigger);

The getScheduledTrigger() method returns a ScheduledTriggerDef object. To initiate execute, the client calls the ScheduledTriggerDef's schedule() and cancel() methods.

If you are setting up a repeating schedule, you might also use the utility class TimeRepeat, which we ship with this package. Here is a simple example of how to use the TimeRepeat class to set up a regular schedule for a ScheduledTrigger that repeats every 10 seconds.

  T3Client t3 = new T3Client("t3://localhost:7001");
  t3.connect();

  Scheduler scheduler = new Scheduler(new TimeRepeat(1000 * 10));
  Trigger   trigger   = new Trigger("examples.time.MyTrigger");

  ScheduledTriggerDef std =
    t3.services.time().getScheduledTrigger(scheduler, trigger);

  std.schedule();

Top

Setting up complex schedules

You can design arbitrarily complex schedules with the schedule() method of a Schedulable object. Here are some examples and tips on scheduling.

There are several ways in which the argument to the schedule() method can describe the execution time:

  • The current time, in milliseconds since the epoch.
  • A specific future date and time, in a millisecond representation by performing date arithmetic using standard Java classes (such as java.util.Date).

The schedule() method returns a long value, which allows you to set up repeating triggers. Simply return the time at which the schedule() method was last called plus the interval (in milliseconds) at which the schedule should repeat.

Rescheduling

In this example, we write the schedule() method to delay for an incrementing interval between each call to the trigger() method. The schedule() and trigger() methods are implemented in the same class in this example. (Please read the release note about the trigger() method.)

In the trigger() method, we set an incrementing delay, using a private int delay, which we initialize to zero in the class constructor. Each time the trigger is called, it incrementally adjusts its own schedule.

  public void trigger() {
    System.out.println("Trigger called");
    // Carry out some arbitrary tasks . . . 
    System.out.println("Trigger completed");
    // Add a thousand milliseconds to the delay
    delay += 1000;
  }

In the schedule() method, we we return the next execution of the trigger as the time of the last scheduled execution, plus the delay incremented by the last scheduled execution (in milliseconds). We also include an upper bounds on the delay to end the scheduling.

  public long schedule(long t) {
    System.out.println("--------------------------------------");
    if (delay > 10000) {
      System.out.println("Cancelling Timer");
      return 0;
    }
    else {
      System.out.println("Scheduling next trigger for " +
                         delay/1000 + " seconds");
      return t + delay;
    }
  }

Stopping a ScheduledTrigger

There are two ways to stop a ScheduledTrigger:

  • Call the ScheduledTrigger's cancel() method.
  • Return zero (0) when the schedule() method is called ends the scheduling.

There is some slight difference in these two methods. If you return zero from the schedule() method, the schedule is immediately ended. If you call a ScheduledTrigger's cancel() method, the clock continues to run until the next scheduled instance of the trigger(), at which point it is cancelled.

Top

Change history

Release 4.0.1

Fixed bug so that ScheduledTriggers are properly cancelled on disconnect and garbage collection is carried out successfully. This was exposed in some simple bean programs that used the Time service indirectly.

Release 3.0

First released.

 

Copyright © 2000 BEA Systems, Inc. All rights reserved.
Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.
Last updated 01/13/1999