© 2006 Carnegie Mellon University Creating Custom Containers with Generative Techniques Generative...

25
© 2006 Carnegie Mellon University Creating Custom Containers with Generative Techniques Generative Programming and Component Engineering (GPCE'06) Portland, Oregon Gabriel Moreno October 24, 2006
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    218
  • download

    0

Transcript of © 2006 Carnegie Mellon University Creating Custom Containers with Generative Techniques Generative...

© 2006 Carnegie Mellon University

Creating Custom Containers with Generative Techniques

Generative Programming and Component Engineering (GPCE'06)Portland, Oregon

Gabriel MorenoOctober 24, 2006

2

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Overview

Stub and Skeleton Generation

• A different approach to generate stubs and skeletons.

— Does not use a special interface description language (IDL).

— Does not require a special purpose compiler.

— Combines AspectC++ and template meta-programming.

Composing Non-functional Features

• An AOP-based approach to compose non-functional features or services.

3

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Component Containers

Mediate the interaction of a component with the runtime environment and with other components.

Provide non-functional services or features:

• Not directly related with the function a component has to carry out.

• Usually more difficult to implement than the core logic of a component.

• Often provide mechanisms that directly contribute to quality attributes.

• Examples include:

— Component instance life-cycle management

— Thread management

— Component interaction

— Persistency, transactions

4

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Why Custom Containers

To simplify component interactions.

• Generated Stubs/Skeletons allow developers to

— Use component-specific interfaces instead of component-model interfaces.

— Invoke other components by means of simple procedure call (even if the other component executes in a different thread or computer).

— Avoid dealing with the complexities of distributed computing (e.g., marshaling/unmarshaling arguments).

To support different combinations of non-functional services to fit an application’s needs.

• Different applications may need different non-functional features.

• Fixed set of containers with pre-defined features is not enough.

— Different combinations of services may be needed

5

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

The Inner Container:Automatic Generation of Stubs and Skeletons

6

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Pin Component Model Overview

Simple lightweight component technology.

Supports pure assembly

• Components are assembled together byconnecting a source pin to a sink pin.

• No “glue” code

Interaction through pins

• Synchronous and asynchronous

• A source pin produces a stimulus received by a sink pin

• The behavior of a component is encapsulated in a reaction

• Stimuli are messages that may carry data

• Pins have a data signature (produced and consumed parameters)

7

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Pin Component and Container

Pin Component

<<delegate>>

PinComponent

This is a DLL

This is a DLLThis component is assembled at runtime

ContainerServicesComponentCore

Custom Code

ComponentCore ContainerServices

PinComponent

Container

Container

ComponentInstanceComponentInstance

<<delegate>>

8

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Pin Component Example

SensorMonitor component

• Has an asynchronous sink pin triggerused to invoke the component.

sink asynch trigger();

• Has a synchronous source pin convert to request measurement units conversion to another component.

source synch convert(produce int a, produce int b, consume float result);

• Has an asynchronous source pin alarm to issue an alarm if the measured value surpasses a threshold.

source unicast alarm(produce string message);

SensorMonitor

convert

trigger

alarm

9

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Component Code Without Stubs

BOOL reactionHandler(Reaction* pReaction, CommonMessage *pMsg) { if (pMsg->type != PIN_MSG) { return TRUE; // don't care about others } int readingA = readSensor(0); int readingB = readSensor(1); IpcPort_Message message; IpcPort_Message answer; int answerDataSize; int* pNextArg = (int*) message.data; int dataSize = 0; *pNextArg++ = readingA; dataSize += sizeof(int); *pNextArg++ = readingB; dataSize += sizeof(int); sendOutSourcePinWait(pReaction, SOURCE_CONVERT, &message, dataSize, &answer, &answerDataSize, IPCPORT_WAITFOREVER, 0);

float result = *((float*) answer.data);

if (result > THRESHOLD) { // send alarm SPrintf((char*) message.data, "ALARM: SensorMonitor\n"); sendOutSourcePin(pReaction, SOURCE_ALARM, &message, strlen((char*) message.data) + 1, IPCPORT_WAITFOREVER); } return TRUE;}

The code in RED is not directly related to the functional logic of the component.

• The functional logic is entangled with marshaling/unmarshaling code.

The code in BLUE does not reflect the signature of the pin being used.

sendOutSourcePinWait(pReaction, SOURCE_CONVERT, &message, dataSize, &answer, &answerDataSize, IPCPORT_WAITFOREVER, 0);

10

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Approach to Stub and Skeleton Generation

Typical approaches use special purpose compilers

• CORBA uses an IDL to specify the component interface and an IDL compiler.

• EJB takes advantage of Java reflection to extract the component interface and uses a compiler to generate code (e.g., ejbc)

The approach presented here uses a general purpose compiler

• Uses AspectC++ compile-time join point API as a compile-time reflection mechanism.

• Exploits the generative capabilities of template meta-programming in C++.

• Uses AspectC++ to weave in the generated code.

11

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Source Pin Stub

The objective of the stub is to make interaction through a source pin as simple as a function call.

The developer only needs to declare a stub function for the source pin.

source synch convert(produce int a, produce int b, consume float result);

int source_synch_0(Reaction* pReaction, int a, int b, float* result);

Convention used to distinguish produced and consumed parameters

• Produced passed by value

• Consumed passed by pointer

12

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Inserting the Generated Stub Code

An around advice is used to replace all the calls to the stub function with the generated stub code.

Template meta-programs are invoked to generate the custom code.

aspect SourcePinStub { advice call("int source_synch_%(Reaction*, ...)") : around () { ... /* >>> Custom code: marshal produced parameters */ success = sendOutSourcePinWait(...); if (success) {

/* >>> Custom code: unmarshal consumed parameters */ } *tjp->result() = success; }};

13

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Basic Marshaling Meta-program

Iterates over the list of arguments of the stub function by recursively instantiating a template.

The static method execute in the template has the code to be emitted.

AspectC++ join point API provides statically typed methods to get the value of an argument indexed by a compile-time index.

The marshal function is overloaded for each supported type.

template<class TJoinPoint, int N> struct MarshalParams { static inline int execute(TJoinPoint* tjp) { marshal(*tjp->template arg<TJoinPoint::ARGS - N>()); return MarshalParams<TJoinPoint, N - 1>::execute(tjp); }};

14

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Deciding What to Marshal

When generating the source pin stub code, only produced parameters have to be marshaled.

Trait templates are used to encode meta-information of a type to indicate whether arguments of that type are included in a marshaling operation.

A code selection meta-programming technique is used to generate code to marshal or skip an argument based on the results of querying the trait templates.

SourceProduce<int>::include == trueSourceProduce<int*>::include == false

15

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Using the Generated Stubs

Componen Code without Stubs Component Code with Stubs

BOOL reactionHandler(Reaction* pReaction, CommonMessage *pMsg) { if (pMsg->type != PIN_MSG) { return TRUE; // don't care about others } int readingA = readSensor(0); int readingB = readSensor(1); IpcPort_Message message; IpcPort_Message answer; int answerDataSize; int* pNextArg = (int*) message.data; int dataSize = 0; *pNextArg++ = readingA; dataSize += sizeof(int); *pNextArg++ = readingB; dataSize += sizeof(int); sendOutSourcePinWait(pReaction, SOURCE_CONVERT, &message, dataSize, &answer, &answerDataSize, IPCPORT_WAITFOREVER, 0);

float result = *((float*) answer.data);

if (result > THRESHOLD) { // send alarm SPrintf((char*) message.data, "ALARM: SensorMonitor\n"); sendOutSourcePin(pReaction, SOURCE_ALARM, &message, strlen((char*) message.data) + 1, IPCPORT_WAITFOREVER); } return TRUE;}

int source_synch_0(Reaction* pReaction, int a, int b, float* result);int source_unicast_1(Reaction* pReaction, char* message);

BOOL reactionHandler(Reaction* pReaction, CommonMessage *pMsg) { if (pMsg->type == PIN_MSG) { int readingA = readSensor(pReaction, 0); int readingB = readSensor(pReaction, 1); float result; source_synch_0(pReaction, readingA, readingB, &result);

if (result > THRESHOLD) { // send alarm source_unicast_1(pReaction, "ALARM: SensorMonitor\n"); } } return TRUE;}

source_synch_0(pReaction, readingA, readingB, &result);

16

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Advantages and Limitations

Advantages

• Since all the methods and functions in the meta-program are declared inline, the C++ compiler generates optimized code that is not recursive and does not have function calls.

• The conditionals in the meta-program are evaluated at compile-time.

• Does not use runtime reflection.

Limitations

• Pin indexes instead of pin names are used in the pin functions.

• The declaration of a pin function still does not relieve the developer from declaring the pin in the component’s introspection data structures.

17

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Custom Containers:Composing Non-Functional Features

18

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Non-functional Features in Containers

Containers provide non-functional features or services that application developers can use.

This enables separation of concerns, allowing component developers to focus on the functional logic.

However, usually component technologies provide a limited number of container types with predefined features.

• For example, session, entity, or message-driven in EJB.

Containers should be adaptable to different requirements, which may translate into different combinations of non-functional features.

19

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Using AOP to Compose Features

Non-functional features such as transactions, persistency, security, are cross-cutting concerns.

AOP can be used to modularize and compose them.

Using aspects directly on components has some disadvantages

• Requires component source code.

• Does not allow using the same component binary with different features.

• May create dependencies on internal elements of the component.

20

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Features as Aspects Advising the Container

This approach uses aspects to advise the container

• Exploits the fact that the container mediates all the component’s interactions through known and stable interfaces.

• Since the container controls the component life cycle, aspects have visibility into the component state from the point of view of the runtime.

• Does not require the component source code.

• Allows using the same component core binary in different settings by deploying it into containers with different features

21

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Advantages and Limitations

Advantages

• No new AOP language required.

• Compile-time weaving and no runtime reflection is more suitable for real-time and embedded systems.

Limitations

• Issues with the order of composition of features.

— For some combinations of features, the order of composition is important. For example, encryption and compression.

• Constraint to only use the container interfaces for pointcuts.

— We need more case studies to find out whether that limits the kind of features that can be implemented in this way.

22

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Conclusion

23

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Related Work

Stub and Skeleton Generation

• Gal et al., “On aspect-orientation in distributed real-time dependable systems.” (WORDS’02)

• Lohmann et al., “Generic advice: On the combination of AOP with generative programming in AspectC++.” (GPCE’04)

Composing non-functional services in containers

• Aigner et al., “Tailor-made containers: Modeling non-functional middleware service.” (NfC’04).

• Duclos et al., “Describing and using non functional aspects in component based applications.” (AOSD’02)

• JBoss proprietary AOP extensions.

— Allow composing features but require runtime reflection and traversing a list of interceptors at runtime.

24

Creating Custom Containers with Generative TechniquesGabriel Moreno, October 24, 2006

© 2006 Carnegie Mellon University

Summary

Presented an approach to generate statically typed stubs and skeletons.

• Does not require a special purpose compiler.

• Combines AspectC++ and template-metaprogramming.

Proposed an approach to compose different non-functional features in containers.

• Features are implemented as aspects.

• These aspects advise the container instead of the component.