Reading C2-style Applications Built in c2.fw

Post on 06-Feb-2016

43 views 0 download

Tags:

description

Reading C2-style Applications Built in c2.fw. Eric M. Dashofy edashofy@ics.uci.edu For ICS 52 October 20, 2004. Overview. Software architectures The C2 architectural style With live example The Klax application. Software Architecture: Basic Elements. Interfaces. Clock. Component. - PowerPoint PPT Presentation

transcript

Reading C2-style Applications Built in c2.fw

Eric M. Dashofyedashofy@ics.uci.edu

For ICS 52October 20, 2004

Overview Software architectures The C2 architectural style

With live example The Klax application

Software Architecture: Basic Elements

Clock Component

Interfaces

Bus1

Connector

Interfaces

Software Architecture: Basic Elements (cont).

Clock

Bus1

LCDDriver

Links

Configuration

An Architectural Style One definition of an architectural style: An architectural style is a named set of

constraints (e.g., rules) you put on your development Constraints may be topological, behavioral,

communication-oriented, you name it This can complicate development because these

constraints may be inconvenient or unfamiliar BUT architectural styles elicit beneficial system

properties that would be really hard to get otherwise

Examples from building architecture:

1. Name some constraints in each style

2. Name some benefits (-ilities) elicited by each style.

The C2 Architectural Style Topological Constraints

All components, connectors have two interfaces, “top” and “bottom”

Components can be connected to 0-1 connector on each interface

Connectors can be connected to 0+ components or connectors on each interface

The C2 Architectural Style Communication Constraints

Components & connectors communicate using only independent events or messages

• Requests go up (“requests rise”)• Notifications go down• No passing pointers

Components & connectors communicate asynchronously

• Can send/receive events at any time• No blocking!

The C2 Architectural Style Dependency Constraints

Components may make assumptions about services provided above them

• But not who is providing them Components may NOT make assumptions

about services provided below them Concurrency Constraints

Each component & connector assumes it’s running in its own thread of control

Live ExampleDataStore

GUI

GUIInterpreter

Alarm

Live ExampleDataStore

GUI

GUIInterpreter

Alarm

Stores data; emits

notifications whenever data

changes.

Live ExampleDataStore

GUI

GUIInterpreter

Alarm

Interprets basic GUI actions &

translates them into data store

operations

Live ExampleDataStore

GUI

GUIInterpreter

Alarm

Rings a bell whenever value

of X changes

Live ExampleDataStore

GUI

GUIInterpreter

AlarmAccept & process

user actions

Live ExampleDataStore

GUI

GUIInterpreter

AlarmBus connector – routes messages

Live ExampleDataStore

GUI

GUIInterpreter

Alarm

What –ilities does C2 buy us? What do you think?

-ilities bought by C2 Flexibility

Loose coupling lets you swap out components, interpose components

Flexible connectors allow run-time changes Distributability

Since no assumption of shared address space, distributing an app across machines is easy

Visibility Since all messages go through connectors, they are easy

to catch and log Parallelizability

One-thread-per-brick means multiprocessor machines are effectively utilized

Event-based vs. OO Event-based

Communication by events

Mostly asynchronous Requests emitted to

unknown parties Responses and state

changes go to many parties

No shared pointers

Object Oriented Communication by

procedure calls Mostly synchronous Requests emitted to

named party only Responses to caller

only, state changes to many

Lots of shared pointers

Implementing a C2 architecture

C2 architecture

Application (implemented)

Java/JVM

Native OS

Implemented by…

Uses services provided by…

??? How do we bridge this gap?

Event-basedWorld

Object-orientedWorld

Implementing a C2 architecture

C2 architecture

Application (implemented)

Java/JVM

Native OS

Implemented by…

Uses services provided by…

Architecture Framework

Uses services provided by…

Uses services provided by…

Event-basedWorld

Object-orientedWorld

What’s an architecture framework? An architecture framework is

software that helps to bridge the gaps between an architectural style and a particular implementation platform.

Example C2 World

Components Connectors Events Links Many threads Asynchronous

communication

Java World Objects Method calls Parameters References Few threads Synchronous

communication

Enter c2.fw c2.fw is an architecture framework for the

C2 style built in Java, providing: Abstract base classes for components,

connectors Reusable connectors (local & network) (Pluggable) topology management (Pluggable) message queuing policies (Pluggable) threading policies

Essentially, c2.fw does the hard work, components and connectors simply implement behaviors.

What does a message look like? In c2.fw, a message can be any

serializable (e.g. no pointers) object NamedPropertyMessages (or

subclasses) are popular though Have a String name Plus a set of name-value pairs

• e.g. {“description”, “Rectangle 1”}• e.g. {“width”, 123}• e.g. {“color”, java.awt.Color.BLACK}

“Reading” a c2.fw application Basic format Lifecycle methods:

init(), begin(), end(), destroy() start(), stop(), suspend(), resume()

Handling messages void handle(Message m)

Sending messages sendToAll(Message m, Interface i)

Your basic c2.fw component…package edu.uci.ics.mypackage;

import c2.fw.*; //import c2.fw packageimport c2.legacy.*; //import support for 2-interface //C2 components

Your basic c2.fw component…package edu.uci.ics.mypackage;

import c2.fw.*; //import c2.fw packageimport c2.legacy.*; //import support for 2-interface //C2 components

public class MyC2Component extends AbstractC2Brick{

}

Implements lots of boilerplate functionality from the base c2.fw.Brick

interface; declares a top interface topIface and a bottom interface

bottomIface.

A boilerplate c2.fw component…package edu.uci.ics.mypackage;

import c2.fw.*; //import c2.fw packageimport c2.legacy.*; //import support for 2-interface //C2 components

public class MyC2Component extends AbstractC2Brick{

public MyC2Component(Identifier id){ super(id); }

}

Each component or connector has a unique identifier.

A boilerplate c2.fw component…package edu.uci.ics.mypackage;

import c2.fw.*; //import c2.fw packageimport c2.legacy.*; //import support for 2-interface //C2 components

public class MyC2Component extends AbstractC2Brick{

public MyC2Component(Identifier id){ super(id); }

public void begin(){ //called automatically by fw. //send out initial events }}

Lifecycle Methodspublic void init(){ //called when component/connector is created //but component not guaranteed to be hooked up}

public void begin(){ //called when component/connector is hooked up //in the architecture, should send initial messages}

public void end(){ //called when component/connector is about to be //unhooked, should send final messages}

public void destroy(){ //called when component/connector is about to be //destroyed}

A boilerplate c2.fw component…package edu.uci.ics.mypackage;

import c2.fw.*; //import c2.fw packageimport c2.legacy.*; //import support for 2-interface //C2 components

public class MyC2Component extends AbstractC2Brick{

public MyC2Component(Identifier id){ super(id); }

public void begin(){ //called automatically by fw. //send out initial events }

public void handle(Message m){ //handle message }}

Implementing handle() //handle() method for our hypothetical alarm component //Called automatically when component receives a message //Should ring bell whenever value of ‘X’ changes

public void handle(Message m){ //handle message

}

Implementing handle() //handle() method for our hypothetical alarm component

public void handle(Message m){ //handle message

if(m instanceof NamedPropertyMessage){ NamedPropertyMessage npm = (NamedPropertyMessage)m; }

}

Implementing handle() //handle() method for our hypothetical alarm component

public void handle(Message m){ //handle message

if(m instanceof NamedPropertyMessage){ NamedPropertyMessage npm = (NamedPropertyMessage)m; String name = npm.getName(); if((name != null) && (name.equals(“valueChanged”)){

} } }

Implementing handle() //handle() method for our hypothetical alarm component

public void handle(Message m){ //handle message

if(m instanceof NamedPropertyMessage){ NamedPropertyMessage npm = (NamedPropertyMessage)m; String name = npm.getName(); if((name != null) && (name.equals(“valueChanged”)){ String varName = (String)npm.getParameter(“varName”); if((varName != null) && (varName.equals(“x”)){ } } } }

Implementing handle() //handle() method for our hypothetical alarm component

public void handle(Message m){ //handle message

if(m instanceof NamedPropertyMessage){ NamedPropertyMessage npm = (NamedPropertyMessage)m; String name = npm.getName(); if((name != null) && (name.equals(“valueChanged”)){ String varName = (String)npm.getParameter(“varName”); if((varName != null) && (varName.equals(“x”)){ ringBell(); NamedPropertyMessage rnpm = new NamedPropertyMessage(“AlarmFired”); rnpm.addProperty(“time”, System.currentTimeMillis()); sendToAll(rnpm, bottomIface); } } } }

Implementing handle()If we care, we could have checked what interface that message came in on:

if(m.getDestination().getInterfaceIdentifier().equals( AbstractC2Brick.TOP_INTERFACE_ID)){

//it’s a notification

}