JDA: A Step Towards Large-Scale Reuse on the Web - CiteSeerX

2 downloads 0 Views 642KB Size Report
JDA suggests that large- scale reuse and arbitrary remixing of Web applications can be realized using currently existing technologies. Categories and Subject ...
JDA: A Step Towards Large-Scale Reuse on the Web Lim, Seung Chan [ Slim ]

Lucas, Peter

MAYA Design Inc. 2730 Sidney St. Building 2 Suite 300 Pittsburgh, PA USA +1-412-488-2900

MAYA Design Inc. 2730 Sidney St. Building 2 Suite 300 Pittsburgh, PA USA +1-412-488-2900

[email protected]

[email protected]

Abstract The Web is maturing as a rich application development platform, and efforts are being made to provide richer and more dynamic interactions using JavaScript. JavaScript-based Web applications such as Google Maps have gained extra attention because they can be easily included in HTML for reuse. Unfortunately, various technical hurdles have made it difficult for JavaScript reuse to extend beyond its current state. Furthermore, JavaScript reuse is still out of reach for a large portion of the Web user base unversed in the use of programming languages. In this paper, we dive deeper into our previous work on the JavaScript Dataflow Architecture (JDA). JDA is intended for Web client applications written using HTML and JavaScript. We discuss the ways in which the architecture addresses many of the hurdles that modern Web client applications face in the realm of large-scale reuse and remixing. JDA aims to provide an ecosystem comprised of black box components operating within a JavaScript-based asynchronous message-passing environment. The environment allows you to use simple HTML to assemble Web applications from JavaScript black boxes scattered around the World Wide Web. No programming skill is required in their assembly, and no plug-ins or applets are required for their execution. Furthermore, the architecture extends the black box metaphor beyond the boundaries of JavaScript and allows multiple JavaScript components contained within an HTML file to be reused as a whole. A detailed account of an early prototype is discussed, and research is being done to improve it. JDA suggests that largescale reuse and arbitrary remixing of Web applications can be realized using currently existing technologies. Categories and Subject Descriptors D.2.2, [Software Engineering]: Design Tools and Techniques – Modules and interfaces D.2.11, [Software Engineering]: Software Architectures – Domain-specific architectures, Patterns. D.2.13, [Software Engineering]: Reusable Software – Domain engineering, Reuse models General Terms Design, Experimentation Keywords Information Devices Architecture, Dataflow Architecture, Rich Web Application, Web Engineering, JavaScript, Composition, Black Box Reuse Copyright is held by the author/owner(s). OOPSLA’06 October 22–26, 2006, Portland, Oregon, USA. ACM 1-59593-491-X/06/0010.

1. Introduction As the installed base of modern Web browsers grew to capture the overwhelming majority of the Internet user base [1], the Web browser evolved from being a software product for viewing hypertext documents to a viable platform on which rich applications can be hosted. With the recognition of the AJAX pattern as a way to provide a more responsive and richer experience on the Web, an increasing number of Web-based systems have begun making extensive use of JavaScript. A recent study by Damith Rajapakse et al. shows that the benefits of reuse-based methods for modern Web applications are high [2]. Efforts such as Back Base [3], Dojo [4], and reusable UI libraries from Yahoo! [5] are all attempts at tackling the challenge of JavaScript reuse. A phenomenon that best showcases the power of reuse on the Web is the Web mash up. A Web mash up is a Website or Web application that seamlessly combines content from more than one source into an integrated experience [6]. There have been numerous mash ups done involving RSS or Atom feeds with Google Maps, for example. Such mash ups render geographical data originating from sources other than Google on Google Maps. Given the popularity and potential usefulness of such mash ups, it is a shame that there are not more reusable components such as Google Maps. To further promote the proliferation of rich user experience on the Web, it is vital to have a simple reuse paradigm paired with a thriving market in which high-quality components can flourish [7]. Earlier efforts such as DynAPI [8] and other JavaScript frameworks promised to bring richer interaction to the, then, mostly static Web sites. However, technical hurdles such as the lack of module namespacing, worries about vendor lock-in, large download sizes, steep learning curves, and the my-way-or-thehighway personalities of certain frameworks, kept large-scale reuse out of the mainstream. Furthermore, since the perceived benefit of richer interaction patterns for traditional Web sites were minimal, no significant attempts were made to resolve these issues. In our previous paper on the Javascript Dataflow Architecture (then referred to as the Javascript Devices Architecture) [9], we described how Web-based systems could be built from black box composition. In this paper, we dive deeper into the philosophies behind the design of JDA, as well as its various implementation details, to showcase how JDA aims to realize large-scale reuse on the Web.

As its name indicates, JDA adopts a form of dataflow architecture. In JDA, Web applications are built from composing black boxes we call infotrons. Infotrons take on the well-known characteristics of black box components such as a lower learning curve and higher reusability [10]. Such traits make the architecture attractive to both novices and experts alike. The architecture allows applications to be assembled from infotrons written in JavaScript and/or HTML. HTML infotrons are nested encapsulations of one or more infotrons. Such nesting provides hierarchical decomposition to the architecture. As the configuration of the assembly is done using HTML, no JavaScript knowledge is required in the reuse process. The composed infotrons communicate with one another via an asynchronous message-passing infrastructure called Star. Lastly, JDA is not a kitchen-sink development framework, but a reference implementation of a general architecture and a style for design called the Information Devices Architecture (IDA). IDA is an ongoing research project being carried out at MAYA Design to provide scalability, tractability, and comprehensiveness to evolving systems. The implementation of JDA is lightweight, and you’re free to incorporate third-party JavaScript APIs, objects and/or design patterns as necessary.

1.1 Hurdles in JavaScript Reuse The first problem that plagues JavaScript reuse is the lack of module-level scoping of namespaces. Most modern high-level programming languages implement the ability to import library modules. When modules are imported, their namespace is kept separate from the namespace of the context to which they are being imported. This frees the developers from worrying about potential name collisions. Since such a feature is absent in JavaScript, developers have no choice but to import code written by third parties and pray that the names of variables and functions do not collide. The second problem involves dynamic loading of JavaScript. Elements such as “img” trigger an “onload” event when they finish loading the associated resource over HTTP. However, the “script” element used to load JavaScript does not trigger such an event across all browsers. As a result, it is difficult to be certain of the time when the script has been fully loaded and interpreted. This forces developers to play a guessing game to figure out when the features of the external API is available for use. One existing technique that tries to remedy this problem includes using document.write. However, this technique cannot be used once the HTML page has been fully loaded. Another technique is to use the AJAX pattern to retrieve the JavaScript source code. The retrieved text content can then be passed as an argument to the eval function for synchronous interpretation. Besides the fact that this requires a fair amount of plumbing, the main problem with the approach is that it cannot be used to retrieve JavaScript from third-party domains. To ensure largescale reuse, the ability to load JavaScript from third-party domains is crucial. Yet another approach requires including a function call at the end of the script being dynamically loaded. The technique essentially substitutes the need for an “onload” handler with an explicit

function call. This solution is very simple, and exhibits none of the symptoms of the other approaches. However, there is no standard signature for such a function intended for large-scale reuse. The third issue is less technical. Unfortunately, there has been very little effort, if any, to promote a standardization of interfaces. Based on the current paradigm of object or API reuse, you must hardcode functions and method names in the code to be able to take advantage of their features. A side effect of this approach is that it can lead to vendor lock-in that makes it difficult for system developers to substitute an API provided by vendor A with one provided by vendor B. Lastly, JavaScript reuse may come with a steep learning curve and is accessible only to those versed in the language. Given the reuse benefit HTML authors have experienced due to is simplicity, it is a shame that a similar paradigm does not exist for JavaScript. The ability to make integration of reusable JavaScript easier would be a welcomed step toward large-scale reuse on the Web.

1.2 Example of Successful Reuse One of the best, yet oft overlooked, examples of highly extensible software systems is the UNIX pipe [11]. In UNIX, different executables can interact via a pipe, and as long as the output of the source executable matches the input requirement of the target, a whole new application can be built from their assembly. As with other black box paradigms, it is not necessary to understand how the internals of the individual executables work, as long as you know that, for example, ls outputs lines of text and that grep can take that as input to print out only the lines that match the given text pattern. It is also possible to substitute grep with egrep for its benefits, since they share the same interface.

2. IDA Terminologies Before discussing the specifics of JDA, it is important that we remember that JDA is a reference implementation of IDA. In this section, we introduce the readers to the basic terminologies used in the paper to refer to the various abstractions that JDA has adopted from IDA. Moreover, we will be using the term “device” over “component” as a catchall phrase that spans across binary compiled software modules, interpreted software modules, as well as hardware modules. Italics will denote these terminologies as they appear across the paper.

2.1 Fundamental Abstractions In IDA, there are three main abstractions. These abstractions serve as a way to allow system designers to think of the design at hand rather than the implementation details.

2.1.1 Infotrons An information device, or an infotron, is a black box that can capture, process, store, transmit, transduce and/or display information.

2.1.2 Messages Messages are discrete bundles of information passed from one infotron to another.

2.1.3 Channels To define the compositional structure of the infotrons that make up a system, we adopt a wiring paradigm. The paradigm is

referred to as establishing channels. Channels are definite, directed paths between infotrons along which messages travel. Given our use of the black box pattern, the infotrons themselves are unaware of the destination of the message being emitted from them.

include black box reuse, black box composition, asynchronous message passing, hierarchical decomposition, universal uniqueness, and model-driven development.

2.2 Additional Terminologies

3.1 Black Box Reuse

The following IDA terminologies are also important in understanding the architecture presented in this paper.

2.2.1 Blueprint A blueprint is a specification or a set of specifications that can be passed to a constructor.

2.2.2 Constructor A constructor is an infotron capable of producing the specified running instances of infotrons described by a blueprint.

2.2.3 Domain Domain is an encapsulation of one or more infotrons capable of having channels established with any other. A domain is, itself, considered an infotron, and may also recursively contain other domains.

2.2.4 Terminals Terminals are infotrons that belong to more than one domain. They serve as the input and output ports for infotrons through which messages flow. Each input terminal has a bounded buffer size that dictates how big of a buffer exists to queue up messages. This promotes tractable use of system resources.

2.2.5 Star Star is a platform-specific runtime kernel that provides the scheduling of infotron execution and facilitates asynchronous message passing among infotrons. It may also provide various types of management facilities such as memory allocation, bootstrapping, and channel establishment. An analogy can be made to a stripped down micro kernel such as Mach [12]. Star is also similar to the massively concurrent message-passing environment proposed by Agha [13] based on the Actors model described by Hewitt et al. [14]. Certain guarantees are made by Star’s message-passing infrastructure and others are not. For example, Star guarantees that when messages travel from a terminal through a single channel, the order in which they are received at the other end of the channel is preserved. Furthermore, Star guarantees that only one message is delivered to an infotron at any given time. In other words, each infotron instance is guaranteed to be executing inside a single thread. However, the order in which messages arrive is not guaranteed across multiple channels. Messages are delivered in a breadth-first manner.

2.2.6 Properties Property/value pairs represent a standardized way for infotrons to selectively expose their internal state to the outside world. By modifying the values of these named properties, one can customize the behavior of any given infotron.

3. Design Philosophy The design of the proposed architecture is based on a carefully selected set of software engineering patterns. These patterns

In this section, we discuss how these patterns relate to the design philosophies behind the proposed architecture. The proposed architecture approaches reusability by allowing you to build systems purely out of loosely coupled black boxes. One of the main advantages of black box reuse is that no intimate knowledge of the inner workings of the device is required for actual reuse [10]. This fact addresses the difficulty of integration. The less knowledge required of the internal workings of the device being reused, the easier it is for the reuse to occur [15]. Black boxes with well-defined interfaces can also give rise to a set of evolving standards. When vendors adopt a standard, substitutability of devices increases. This, in turn, can help alleviate vendor lock-in problems and provide economic benefits to users from increased competition among vendors [16]. One of the drawbacks of building devices as black boxes is that one cannot modify their behavior the way a subclass can in a white box reuse scenario [10]. To make up for this perceived lack of flexibility, our proposed architecture allows black boxes to be independently configurable via the aforementioned use of properties.

3.2 Black Box Composition In order to foster the creation of reusable devices and to build a foundation for extensible systems, it is not enough to start with a monolithic design of a complete solution and then partition it into fragments [17]. The likely benefits of doing so are minimal. Instead, descriptions have to be carefully generalized to allow for reuse in a sufficient number of different contexts. By making composition of black boxes the primary method of system building, we attempt to allow developers to adopt a style of design that will yield reusable and extensible devices and, ultimately, systems.

3.3 Asynchronous Message Passing Dataflow architecture exploits the potential of massive parallelism by allowing program execution to take on behavior similar to that of water. Water, in our case, would be messages flowing from one infotron to another. JDA embraces the benefits of asynchronous message passing for its applicability to continuations [18, 19] and its ability to provide a stronger separation of information and device [51]. The importance of the message-passing pattern is amplified further given the rise of Web services and other similar SOA initiatives. As you’ll see in section 4.7, message passing allows individual devices in the architecture to seamlessly extend beyond the realm defined by the client Web browser and to communicate with other distributed systems on the Web. Unlike other distributed protocols such as DCOM [20] and CORBA [21], JDA promotes a pattern where pure information, not objects, is passed between two infotrons. Furthermore, to address the poor performance characteristics of traditional dataflow architecture design, JDA adopts a form of hybrid dataflow architecture as discussed by Silc et. al [22].

3.4 Hierarchical Decomposition

3.6 Model-Driven Development

When designing a complex structure, it is advisable to discover ways of decomposing the structure into semi-independent devices corresponding to its many functional parts [23]. In this way, complexity can be controlled at each level, and only a reasonable amount can be made visible at any given level. Furthermore, ensuring that the system is built out of simple parts connected by well-defined interfaces allows you to localize most problems and maintain hope that optimizations and fixes to parts can be made without breaking the whole [24]. The design of the OSI network stack, for example, has been very successful at allowing for various extensions, precisely due to its hierarchically layered design [25]. The proposed architecture introduces a notion of an atomic infotron versus that of a domain to make such hierarchical decomposability an inherent part of the architecture.

The benefit of Model-Driven Development (MDD) highlighted in this section refers to its ability to provide automated codegeneration [30]. The model used in our proposed architecture is called the blueprint. The contents found in a blueprint are simply attribute value pairs that may be expressed textually as shown in Figure 1 and Figure 2. The two figures depict the information contained within the blueprints of two atomic infotrons “Timer” and “Alert Box” respectively.

3.4.1 Atomic Infotrons Atomic infotrons are infotrons that are like leaf nodes in a tree. This is the boundary at which black box ends and the facilities provided by the particular implementation language and environment take over. For instance, it is conceivable that an atomic infotron is implemented using imperative languages like C, or JavaScript. Moreover, message handling and posting can be modeled as function calls provided by the environment.

3.4.2 Domains A domain is an infotron that consists of one or more infotrons. Domains may include atomic infotrons and/or recursively include other domains.

Figure 1. “Timer” blueprint

Figure 2. “Alert Box” blueprint Although omitted from the figures to preserve space, blueprints of atomic infotrons contain the code that implements its internals.

From the outset, a domain is just like an atomic infotron. Domains expose terminals, and are composed with other infotrons via channels. A domain can be seamlessly substituted for an atomic infotron and vice versa. This can be especially useful when addressing the issue of granularity faced by traditional dataflow architectures as observed by Lee et al. [26]. Substituting a domain for an atomic infotron is equivalent to adopting a macro or a large-grain dataflow [27]. As atomic infotrons may employ the most appropriate technology, pattern, and algorithm given the environment and circumstance, they can be engineered in the most efficient manner possible.

3.5 Universal Uniqueness Similar to architectures such as JXTA [28] and COM [20], blueprints are assigned Universally Unique IDentifiers (UUID) [30]. The purpose behind assigning a UUID to an entity is to prevent namespace collisions among blueprints that are being reused [52]. The use of UUID also addresses the topic of version control. Let’s say the author of a blueprint decides to release a new version that introduces backward incompatibility, or perhaps the version incurs extra overhead that may not be required by all current users. By assigning the new version of the blueprint a new UUID, those using the older version will be insulated from the change. When the users decide to migrate to the newer version, they can do so by explicitly updating the reference to the blueprint with the newly published UUID.

Figure 3. “Hello World” blueprint Figure 3 shows how the same technique can be used to describe a blueprint of a domain.

The “Hello World” domain shown in Figure 3 contains references to two child blueprints. Information such as the UUID of the child blueprints, their local id, properties, and the channel configuration between them are all contained in the domain blueprint. Figure 4 shows a graphical visualization of this blueprint. This graphical visualization presents blueprints as boxes. The input and output terminals are drawn as labeled female/male receptors, and channels are represented as dashed lines. A domain blueprint can be used to generate the necessary HTML code such as the one found in section 4.4.4 that is ready to be deployed for testing. When a change needs to be made to the system, you can go back and modify the blueprint accordingly to reflect the change and repeat the process. Given the codegeneration step, such Model-Driven Development ensures better synchronization between the design documentation and the deployed system.

Using a standardized global function to declare the blueprint of an atomic infotron allows us to kill two birds with one stone. When this global function is called, it is clear that the script has been fully loaded and interpreted by the JavaScript engine. This frees the developers from the aforementioned uncertainties surrounding the time at which the dynamically loaded JavaScript can be used.

4.2 Universal Uniqueness Assigning a UUID to the blueprint prevents another type of name collision that can affect blueprints scattered around the Web. Efforts such as JSAN address JavaScript name management using a central registry [31]. The use of a UUID allows our proposed architecture to opt instead for a decentralized management of JavaScript source codes.

4.3 Asynchronous Message Passing JDA provides an asynchronous message-passing platform on which infotrons can post messages from its output terminal and handle messages posted to its input terminal. In a message-passing system, as long as the message format is kept consistent, a device developed by vendor A can be more easily substituted with one developed by vendor B. Even if the message format is not identical, inserting a translator in between becomes a very natural activity. Let’s take a closer look at how infotrons engage in the exchange of messages.

4.3.1 Message Handling Figure 4. Visualization of the “Hello World” blueprint

4. Implementation In this section, we discuss the details of the facilities provided by JDA to help Web developers achieve large-scale reuse. We also introduce other aspects of JDA that can benefit the developer community at large. Our prototype implementation makes use of only JavaScript and HTML.

4.1 Code Encapsulation JDA provides a global function called BLUEPRINT. The function takes a UUID, an array of input terminals, and an array of output terminals followed by a function that provides its implementation. A human-readable name may be optionally provided as the last parameter. The following code is the bare minimum required to introduce the blueprint of an atomic infotron to a Web application. BLUEPRINT( “~6B5EAB0E6AD4483e84D3D5EF14C8AEE7”, // UUID [], // array of input terminal names [], // array of output terminal names function(props) { // your code goes here }, “Timer”);

By embedding the implementation function as a parameter of the function BLUEPRINT, the global namespace is left untouched. This technique remedies the namespace collision issue that hampers large-scale JavaScript reuse.

As you might recall, the function BLUEPRINT takes an array of input and output terminals as the second argument. Let’s take a look at the following blueprint of an atomic infotron. BLUEPRINT( “~6B5EAB0E6AD4483e84D3D5EF14C8AEE7”, [ [“%startup”, “onStartUp”, 1] ], [], function(props) { var self = this; self.onStartUp = function(msg) { // your code goes here }; }, “Timer”);

This blueprint describes a single input terminal named “%startup” which is associated with a handler method named “onStartUp”. The handler method is called for each message posted to the terminal. As a side note, “%startup” is a special terminal that, when declared, automatically receives a message to indicate that the system is ready to allow infotrons to start posting messages. The numeric value of 1 found as the last parameter signifies the number of messages that may be allowed to queue up at the terminal before they are dropped.

4.3.2 Message Posting The third argument to the function BLUEPRINT is an array of available output terminals. Messages can be posted to an output terminal using the postMessage method. The following example shows how an infotron can be programmed to post a message (an integer value of 1 in this case) to the “timeout_event” output terminal after 1000 milliseconds elapse:

BLUEPRINT( “~6B5EAB0E6AD4483e84D3D5EF14C8AEE7”, [ [“%startup”, “onStartUp”, 1] ], [ “timeout_event” ], function(props) { var self = this; self.onStartUp = function(msg) { window.setTimeout(_triggerTimeout, 1000); }; function _triggerTimeout() { self.postMessage(“timeout_event”, 1); } }, “Timer”);

4.4 Programming-Free Assembly In our proposed architecture, domain blueprints are authored using HTML. This section shows how this feature allows you to reuse JavaScript to build a system without using the language itself. As you will also see in this section, this feature not only lowers the barrier to building rich Web applications, but also promotes cleaner separation of the UI and its control logic.

4.4.1 Declaration Each of the infotrons found in a domain is declared using the “div” tag. For example, “timer1” specified in the “Hello World” blueprint from Figure 3 can be declared with the following snippet of HTML:


The “id” attribute is a local id that can uniquely identify the infotron in a given HTML file. The “impl” attribute contains the UUID of its blueprint. The “properties” attribute contains key/value pairs that get passed as an argument to the implementation function of the infotron. The details of this process are covered in section 4.4.3. The “script” attribute denotes the URL of the blueprint. For the purpose of efficiency, the “script” attribute is ignored if the blueprint identified by the UUID found in the “impl” attribute already exists in memory. You can also decide to use the conventional “script” tag to load blueprints for atomic infotrons, like so:

Either method makes it possible to reuse blueprints of atomic infotrons loaded from various disparate Web servers around the World Wide Web.

4.4.2 Composition The channel configuration among infotrons can be defined as part of the “div” tag using the “connections” attribute. The snippet below shows how the channel between the input terminal “trigger” on the infotron “alert1” and the output terminal

“timeout_event” on the infotron “timer1” is established as shown in Figure 3.


The value of the “connections” attribute takes the form of comma delimited key/value pairs. The key is the name of the output terminal, and the value is an array that contains one or more sub arrays of an infotron id and input terminal pair connected to the output terminal. A colon separates the key and the value.

4.4.3 Customization Each infotron can be instantiated with a unique set of properties using the “properties” attribute of the “div” tag. The value of the “properties” attribute takes the form of comma-delimited property value pairs. A colon is used after each property name to assign a value for the property. The following HTML snippet shows the use of the “properties” attribute on the “timer1” infotron:


As shown below, properties are passed into the implementation function of each atomic infotron. In this case, the implementation function stores the property “timeout” for later use. BLUEPRINT( “~6B5EAB0E6AD4483e84D3D5EF14C8AEE7”, [ [“%startup”, “onStartUp”, 1] ], [ “timeout_event” ], function(props) { var self = this; var _timeout = props[“timeout”]; self.onStartUp = function(msg) { window.setTimeout(_triggerTimeout, _timeout); }; function _triggerTimeout() { self.postMessage(“timeout_event”, 1); } }, “Timer”);

4.4.4 Sample HTML The following HTML snippet shows how the domain blueprint depicted in Figure 3 can be represented in HTML:



Notice that the UUID of the domain blueprint is denoted using the “meta” tag. The HTML presented above, when constructed inside a Web browser, waits 1000 milliseconds before popping up an alert box that echoes the phrase “Hello World.” Further uses of domain blueprints will be discussed in section 4.6.

4.5 Separation of UI and Control Logic In this section we discuss the ways in which JDA promotes better separation of UI and interaction logic. Once an infotron is constructed, it is free to manipulate the “div” DOM node used for its declaration. The reference to this DOM node is found in a member variable named dom_node. As you’ll see, this becomes especially useful for infotrons that provide user interface elements. In traditional Object-Oriented UI programming, configuration parameters are usually passed to the class constructor or set via method calls as seen in the following example: var table = new RichTable(); table.setNumRows(2); table.setNumCols(5); table.setCell([0, table.setCell([0, table.setCell([0, table.setCell([0, table.setCell([1,

0], 1], 2], 3], 4],

”a”); ”b”]; ”c”); ”d”); ”z”);

table.onClick = function(e) { alert(“clicked!”); }; table.draw();

However, the model preferred by JDA is to proactively render the HTML within the “div” element, and to let the atomic infotron take care of any registration of event handlers that control the user interaction. The following code illustrates this paradigm: BLUEPRINT( “~171D001CDE5344650BD0E2A4297BB0150”, [], [], function(props) { this.dom_node.onclick = function(e) { alert(“clicked”); }; }, “Rich Table”);
abcd
z


There are several benefits to this approach. First, it results in faster rendering compared to the previous technique that uses dynamic DOM node creation. This is not simply a raw performance enhancement, but also an enhancement in the perceived performance witnessed by the user. Moreover, it saves you from having to spend time writing UI generation code. Again, this is not simply about saving time, but actually adhering to the good practice of engaging in data-driven UI programming. Finally, this pattern separates the HTML UI from the JavaScript that provides the control logic. This feature also allows visual designers versed in the use of HTML and CSS to concentrate on detailed styles and the layout of the UI, while programmers concentrate on implementing the control logic. Similar efforts to better separate the UI from the control logic have been attempted by the Behavior package created by Ben Nolan [32]. The main difference between the approach taken by JDA and Behavior is that JDA allows the UI element to choose which control logic to take on, while Behavior uses predetermined path grammar to locate the UI element and bestows it with control logic. Although the distinction may seem subtle, it is an important one. First, requiring the use of JavaScript to parse a path grammar to locate the UI introduces a level of complexity to our purely HTML-based composition model. Second, the use of predetermined paths introduces a tight coupling to the system that we feel is unnecessary. With the UI separated cleanly from its interaction logic, one can also envision adopting the AJAX pattern to separate the data from the UI as well. For example, the values within each tag pair may initially be empty and then become populated via AJAX.

4.6 HTML-Based Hierarchical Decomposition In this section, we discuss the ways in which JDA implements hierarchical decomposition. The technique can be very useful when composing complex, rich Web applications from smaller and simpler rich Web applications.

4.6.1 Domains in JDA The following code snippet shows an example of how a domain is declared in an HTML page:


The tricky part in this snippet is that the “impl” attribute does not reference the UUID of the domain blueprint itself, but rather the UUID of a special blueprint called “Domain Proxy”. The blueprint of the “Domain Proxy” infotron has been specifically developed to facilitate the flow of messages to and from domains that cross HTML frame boundaries. The UUID of the blueprint of

the domain itself can be found in the “impl” attribute of the enclosed “a” element. It should also be noted that we set the “is_proxy” attribute on the “div” element to “true” to make this proxy pattern explicit. When a message arrives at the “Domain Proxy” infotron for the first time, the URL referenced in the “href” attribute of the “a” tag is loaded using a dynamically created “iframe” element. This allows the domain blueprint to be constructed only when it becomes necessary. The benefit to this approach is that it reduces upfront bandwidth usage and latency costs, as well as the computation overhead of constructing the blueprint. Once the domain is constructed, all messages are then routed through the “Domain Proxy” infotron to the domain residing inside the “iframe”. One can also choose to load the URL of the domain blueprint inside a popup window instead of an “iframe”. Setting the “as_popup” property to “true” can achieve this result:


Regardless of the enclosure used, the semantics of message passing remains unchanged. You can also opt to construct domain blueprints as soon as possible, rather than waiting for it to receive its first message. Setting the “defrosts_proactively” property to “true” can achieve this:


The blueprint of the domain referenced by the URL (/helloworld.html in the above example) is nothing more than an HTML page like the one shown in section 4.4.4. Being able to reuse an HTML page as a domain blueprint is a powerful feature of JDA that aims to allow developers to better decompose the system being designed. This also helps division of labor among developers. Domain blueprints declare their input and output terminals via the “meta” tag as follows:

The “%startup” terminal is a special terminal for domains as well, and follows the same semantics as mentioned in section 4.3.1. Domain blueprints do not contain any logic for handling incoming messages. However, the incoming messages can be routed to an atomic infotron for the job. The “meta” tag is used again to denote such channel configuration:

The above snippet describes a connection between its input terminal “trigger_alert” and the input terminal “trigger” of infotron identified in the domain as “alert1”. Now the messages

sent to the input terminal “trigger_alert” of this domain will be routed to the input terminal “trigger” of the infotron “alert1”.

4.6.2 DOM-Renderer Unfortunately, due to browser limitations and bugs, problems can arise when using the “iframe” element to enclose infotrons. First of all, due to cross-site security restrictions it is impossible to communicate with domains constructed from blueprints resident on a third-party domain. For this reason, domain blueprints would have to be served from the same Web server for reuse. Furthermore, the use of the “iframe” element can be especially frustrating when UI elements get clipped within its bounding box. There are also other event and rendering-related bugs that plague certain browsers and cause headaches. To overcome this last limitation, we have developed an extension to JDA called the DOM-Renderer. Although a full-fledged discussion of the DOM-Renderer is out-of-scope, its basic functionality allows atomic infotrons to transplant its child DOM nodes to the top-most document in the HTML frame hierarchy. It also modifies the aforementioned member variable named dom_node so that it points to the transplanted DOM node. The “iframe” is then styled to not take up any space within the window. As these transplanted DOM nodes all reside at the top-most HTML document, there are no more bounding box problems associated with the “iframe”. During internal testing of the prototype, all event and rendering-related bugs pertaining to the use of “iframe” were eliminated with the use of the DOMRenderer.

4.7 Infotron Abstraction for Remote Resources So far, we have talked exclusively about the reuse of devices that are executed inside a Web browser. This section describes how JDA extends the dataflow pattern to access resources available on remote Web servers. There are two main ways Web applications retrieve data. The first approach is to dynamically generate the HTML from the server so the data is embedded within the HTML. Another approach is to use the AJAX pattern to retrieve the data separately, and then to manipulate the DOM to populate the page with the retrieved data. As the former approach is well understood, the techniques illustrated below will discuss how to go about doing the latter in the context of JDA. It should be noted, however, that depending on the requirements of the application, the former approach will make more sense. Both approaches are fully supported by JDA. In order to retain the abstraction of an infotron, JDA allows one to treat server resources such as CGI scripts as just another infotron. One of the benefits of keeping the abstraction intact even when dealing with server resources is that it allows us to use a placeholder that generates dummy data while the server resource is being implemented. The placeholder infotron can be easily swapped with the genuine server resource once it becomes available. To illustrate more clearly how server resources can be modeled as infotrons, let’s look at the system shown in Figure 5.

When the content of the response is returned from the server, it is sent out through its “response” output terminal. The response will be of a native JavaScript type. As the “HTTP Proxy” blueprint is not a special blueprint, you can easily implement a substitute that generates a differently formatted URI, speaks different protocols such as SOAP, or uses interfaces other than XMLHTTPRequest.

Figure 5. Upon construction, the server time is displayed inside a text box. Let’s say that the blueprint for “Server Clock” resides on a remote Web server in the form of a CGI script. Since HTTP communication is required to reach this remote resource and trigger its execution, what JDA allows you to do is to abstract this process inside an infotron. The following HTML shows how one can declare an instance of an infotron that provides such an abstraction.


You’ll notice that the proxy pattern introduced in section 4.6.1 is reintroduced. Here, again, the “is_proxy” attribute of the “div” element has been set to “true” in order to make this proxy pattern explicit. The fact that the UUID of the actual remote service is denoted using the “impl” attribute of the enclosed “a” element is also a familiar pattern. However, there are two differences here. First, the “impl” attribute of the “div” element refers to the UUID of a blueprint called “HTTP Proxy”. Second, “HTTP Proxy”, unlike “Domain Proxy”, is not a special infotron. In other words, one can easily derive a compatible blueprint that provides a different implementation. For example, you can easily wrap a third-party AJAX library as an infotron and use that instead. This particular implementation of the “HTTP Proxy” infotron uses the XMLHTTPRequest object to route all incoming messages as part of an HTTP request. The URL to which the request is sent is prefixed with the string found in the “href” of the enclosed “a” element and suffixed with the name of the input terminal at which the message had arrived. For example, assuming that the Web application is being served on “localhost”, when a message arrives at the “request” input terminal, the URI used for the HTTP request would be formatted as follows: http://localhost/webservice/server_time/request/

The content of the message may be serialized as either XML [33] or JSON [34]. The decision can be made using the “serialization” property. You can also decide between delivering the serialized message as the content of a POST request or as part of the URI of a GET request like so: http://localhost/webservice/server_time/request/?msg=1

In fact, the XMLHTTPRequest object used by the “HTTP Proxy” blueprint introduces a hurdle for large-scale reuse of remote resources; it cannot make HTTP requests to third-party domains. The traditional solution to this problem is to access the third-party Web service via a proxy on your own server [35]. Another possibility is to require the service to adopt HTTP Response Bouncing (HRB) approach [36]. The HRB pattern uses an “iframe” element to re-route the response to a URI that resides on the originating host. This lets us get around the cross-domain restrictions imposed by the Web browser. A third approach is to require the service to support the encoding of the payload as a JavaScript callback [37]. Web Services provided by companies such as Yahoo! support such encoding. No matter which method is used, the dataflow paradigm remains unaffected as long as the infotron abstraction remains intact, and the response generated by the remote resource can be routed back through the infotron’s output terminal.

5. Runtime Environment JDA implements Star using the JavaScript language. Hence, this implementation is referred to as JavaScript Star or JS-Star. JS-Star is a relatively small file weighing in at about 6.5KB when gzipped. When there is no message-passing activity, it sits idle to allow for other parts of the system to utilize the CPU. Unfortunately, the limitations of the JavaScript language made it difficult to create an asynchronous environment based on preemptive multi-tasking. The original implementation used simulated threading via the setTimeout function available through the Web browser’s window interface. The latest implementation forgoes the use of setTimeout and simply implements a straightforward breadth-first message delivery algorithm. This decision was mainly to avoid browser quirks related to the setTimeout function, as well as issues related to unintended popup blocking. A mild level of testing for JS-Star has been conducted on Internet Explorer 6.0, FireFox 1.0, FireFox 1.5, Opera 8.0, Opera 9.0, Safari 1.3, and Safari 2.0 to ensure compatibility across a variety of Web browsers. In this section we describe the interfaces provided by the runtime environment of JS-Star.

5.1 Global Variables and Functions There are four names introduced to the global namespace by JSStar. The first is the function BLUEPRINT that provides code encapsulation as described in section 4.1. The second is __w which is a cached reference to the window object. The third, __d is a cached reference to the document object. Finally, __star is an object that provides access to the interfaces provided by JS-Star.

5.2 Star API Usage As noted above, interfaces provided by JS-Star can be accessed using the global object __star. This section lists the provided public interfaces.

5.2.1 Bootstrap/Shut Down Calling the __star.boot method starts JS-Star’s bootstrapping process. This method should be called below as soon as the DOM is ready. The method does not take any arguments.

__star.connectTerminals([“timer1”, “timeout_event”], [“alert1”, “trigger”])

The disconnectTerminals method allows you to programmatically disconnect a channel connecting two terminals. The following sample code disconnects one of the channels connecting the output terminal “timeout_event” on infotron “timer1” and the input terminal “trigger” on infotron “alert1”: __star.disconnectTerminals([“timer1”, “timeout_event”], [“alert1”, “trigger”])

Calling the __star.shutdown method removes all infotrons and cleans them up by calling their _onDestruct methods (details in section 5.5). At the end of this process the “shutdown” event for JS-Star is triggered (details in section 5.3.2). The method does not take any arguments.

5.2.5 Message Passing

5.2.2 Infotron Creation/Removal

__star.queueMessage(“alert1”, “trigger”, 1)

The addInfotron method allows an existing DOM node to become an instance of a specified blueprint. A set of properties can be provided for parameterization. The method returns false if the infotron could not be immediately constructed because the specified blueprint was not found. If the blueprint is found, the method returns an array of length two where the first item is an array of input terminals and the second item is an array of output terminals that belong to the infotron. The following sample code attempts to instantiate a DOM node with the id “timer1” as an instance of the blueprint with the specified UUID (~6B5EAB0E6AD4483e84D3D5F14C8AEE7). It also passes in the “timeout” property of value 1000: __star.addInfotron(“timer1”, “~6B5EAB0E6AD4483e84D3D5EF14C8AEE7”, {“timeout” : 1000});

The removeInfotron method triggers the _onDestruct method (details in section 5.5) on the infotron and removes it from the domain. The following sample code removes the infotron associated with the id “timer1”: __star.removeInfotron(“timer1”)

5.2.3 Terminal Creation The addOterm method creates an output terminal for an infotron and returns a unique identifier that can be passed into the connectTerminals method. The following sample code creates an output terminal named “timeout_event” for the infotron “timer1”: __star.addOterm(“timer1”, “timeout_event”);

The addIterm method creates an input terminal for an infotron and returns a unique identifier that can be passed into the connectTerminals method. The following sample code creates an input terminal named “trigger” on the infotron “alert1”: __star.addIterm(“alert1”, “trigger”);

5.2.4 Channel Creation/Removal The connectTerminals method allows you to programmatically connect two terminals with a channel. The following sample code connects the output terminal “timeout_event” on infotron “timer1” to the input terminal “trigger” on infotron “alert1”:

The queueMessage method queues up a message directly into an input terminal. The following sample code injects a message (an integer value of 1) into the input terminal “trigger” on infotron “alert1”:

The receiveMessage method is analogous to the queueMessage method, except that it is intended for use by a domain. The following sample code routes a message (an integer value of 2) to whichever input terminal connected to the “%from_parent” input terminal of the domain: __star.receiveMessage(“%from_parent”, 1)

The deliverMessage method delivers a message to an output terminal of a domain. The following sample code routes a message (an integer value of 3) to the output terminal “timeout_event” that belongs to the domain contained within the window/frame referenced by the variable “ref”: __star.deliverMessage(ref, “timeout_event”, 3)

The allowMessagingToChild method is called by a child domain that wishes to alert the parent that it is ready to receive messages. The first argument to the method is the reference to the window/frame the child infotron resides in. The second and third arguments to the method are arrays of input and output terminal names of the child infotron: __star.allowMessagingToChild(__w, [“trigger”]), [“timeout_event”]

5.3 Star Events There are six different events triggered by Star that you can listen for: “bpmiss”, “bpload”, “afterbpload”, “boot”, “afterboot” and “shutdown”. JS-Star provides one method to allow you to register callback functions for these events and another to artificially trigger them. The function signature for the callback takes a single argument, which is an object literal with two members: “type” and “context”. The “type” member will contain a string denoting one of the above mentioned event types, and “context” will contain eventspecific data (details to follow).

5.3.1 Event Listening/Dispatching The addEventListener method registers a callback function for any of the events triggered by JS-Star. The following sample

code registers a callback function referenced by the variable func for the event “bpmiss”: __star.addEventListener(“bpmiss”, func);

The dispatchEvent method artificially dispatches any of the above-mentioned events so as to invoke all of the registered callback functions. The following sample code dispatches the “shutdown” event. No context is provided, as the “shutdown” event does not normally provide any context: __star.dispatchEvent({type:”shutdown”});

5.3.2 Event Details A “bpmiss” event is triggered when JS-Star tries to deliver a message to an infotron that is yet to be constructed because its blueprint was not found in memory. The “context” member is an array containing the id of the infotron that triggered the event and the UUID of the missing blueprint as the first and second items respectively. A “bpload” event is triggered when a new blueprint is loaded into memory via the function BLUEPRINT. The “context” member is an object literal with the members “name”, “iterms”, “oterms” and “uuid” containing the name of the blueprint, array of input terminal names, an array of output terminal names, and the UUID of the blueprint respectively. A “afterbpload” event is triggered after a new blueprint is loaded into memory via the function BLUEPRINT and all infotrons that were delayed construction have been constructed. The “context” member is an object literal with the members “name”, “iterms”, “oterms” and “uuid” containing the name of the blueprint, array of input terminal names, an array of output terminal names, and the UUID of the blueprint respectively. A “boot” event is triggered right before the infotrons start to get constructed as part of the __star.boot method call. The “context” member is the reference to the frame/window object in which JS-Star resides.

5.4.2 Message Handling/Posting The blockAllTerminalsExcept method prevents messages arriving at any input terminal, except the ones specified, from invoking its handler. Messages arriving at the blocked terminals will become queued up until their respective queue limits are reached. The following sample code prevents the handler associated with all input terminals except “trigger” from being invoked: this.blockAllTerminalsExcept([“trigger”])

The blockAllTerminals method prevents messages arriving at all terminals from invoking their associated handlers. The method does not take any arguments. The unblockAllTerminals method allows all previously queued up messages to invoke their handlers and continue the natural flow of messages delivery. The method does not take any arguments. The onMsg method is used to modify the handler function associated with an input terminal. The following sample code registers the function referenced by the variable func to become the handler of all messages delivered to the input terminal “trigger”. this.onMsg(“trigger”, func)

The postMessage method was described in section 4.3.2. The popMessage method is used to pop a message from an input terminal. The following sample code pops and returns the first message queued at the input terminal “trigger”. this.popMessage(“trigger”)

The following five methods are available for logging. However, JS-Star does not provide the implementation for these facilities. These interfaces exist primarily as a hook to an external logging API. They are no-op functions in the absence of an external logging API. this.error(string)

An “afterboot” event is triggered right after all the infotrons are constructed as part of the __star.boot method call. The “context” member is set to null.

this.debug(string)

A “shutdown” event is triggered after all the infotrons have been destructed as part of the __star.shutDown method call. The “context” member is set to null.

this.info(string)

5.4 Infotron API Usage This section lists the member variables and methods provided to each infotron instance.

5.4.1 Member Variables Each infotron instance has access to four member variables: “id”, “name”, “dom_node”, and “bp_uuid” The “id” member variable is the string identifier specified using the “id” attribute on the “div” element used to declare the infotron. The “name” member variable is the string identifier speficified using the “name” attribute on the “div” element used to declare the infotron. The “dom_node” member variable was described in section 4.5. The “bp_uuid” member variable is a string UUID of the blueprint which the infotron is an instance of.

this.caution(string) this.warning(string)

5.5 Infotron Event Handlers The following is a list of event-handling methods that you can override to carry out additional routines of your own. The _onStartUp method is called once right before the very first message arrives at the infotron. The method does not take any arguments. The _onMsgDelivery method is called by Star to deliver a message queued up at an input terminal. If this method is overridden, the original terminal handler associated with the input terminal in the blueprint will not be called. The method takes two arguments: name of the input terminal that received the message and the message itself. The _onDestruct method is called once by Star inside the __star.shutDown method call. If an infotron needs to carry out additional clean up, this would be the method to override. The method does not take any arguments.

5.6 Domain Proxy Specific Interfaces The following two methods are intended for use only by the “Domain Proxy” infotron. The _onConstructInternal method is called by Star on a “Domain Proxy” infotron that receives a message before it has finished constructing its domain. This is the method overridden to lazily construct a domain inside an iframe or a window. The method does not take any arguments. The _onChildConstruct method is called by Star on a “Domain Proxy” infotron when its domain finishes constructing and calls the allowMessageToChild method. The first argument is the id of the element (i.e., iframe/window) that wraps the domain. The second and third arguments are input and output terminals that belong to the constructed domain. The “Domain Proxy” infotron sets its member variable is_not_ready_for_message_pumping to true and only changes it to false after its overridden _onChildConstrunct method is invoked. The “Domain Proxy” infotron uses a member variable named “is_ready_for_message_pumping” to communicate with JS-Star on whether the HTML domain is ready to get messages delivered. The “Domain Proxy” infotron is expected to initially set this member variable to false and only set it to true when its _onChildConstruct method is invoked by JS-Star.

6. Related Work There has been much research in recent years on the subject of compositional software systems that promote reuse. Technologies such as COM [20], CORBA [21], Java beans [38] and, more recently, various forms of Web Services [39] are all great examples. The desire to promote device composition is retained in much the same way in JDA.

consists of solving the namespace collision issue using a centrally managed hierarchical categorization that allows better packaging of unsigned Javascript. JDA attempts to solve the same problem in a decentralized way using Universally Unique IDentifiers. Recent efforts such as the Behavior package developed by Ben Nolan [32] based on the Prototype API [50] tackles an aspect also tackled by JDA: providing for a clean separation of the UI and its control logic. While the Behavior package allows programmers to apply logic to UI elements on a Web page, JDA attempts to flip the equation and empower UI elements to take on logic.

7. Example applications This section discusses the various observations witnessed throughout the development of three Web-based systems built using the proposed architecture. The three Web-based systems were meant to act as an interface to various types of publicly available information such as outdoor events, after-school activities, and public services (Figure 6). The systems provide searching as well as geographical mapping capabilities. Users are also able to drill down to individual search results to find about more about other related information.

7.1 Rapid Prototyping After the requirements for the systems became available, and developers were able to identify the various building blocks that were needed, the development of the individual building blocks was carried out from the bottom up. In other words, developers created task-specific infotrons and composed them to build a system. For example, one of the requirements demanded a view that encoded various types of information such as organizations, facilities, and events as shown in Figure 7.

Other important works such as ACME [40] and ADML [41] have a conceptual overlap with JDA due to their shared objective of abstracting the design from implementation, thus allowing for greater composability among disparate devices. Martin Gaedke et al. had also applied the composition pattern to developing Web server software. [42]. Earlier works on the subject of dataflow architectures intended for programming-in-the-large by DeRemer [43], Arvin and Culler[44], Davis and Keller[45], Dennis and Misunas[46], Karp and Miller [47] share a common goal of large-scale reuse. The aforementioned ideas were primarily intended for desktop applications and/or server software. JDA aims to bring the concept to software running inside a Web browser using HTML and JavaScript. Tools that promote JavaScript reuse on the Web include frameworks such as DynAPI [8], Bindows [48], Dojo [4], Backbase [3], and Microsoft Atlas [49]. To encourage widely differing ways of achieving similar goals by making different tradeoffs, JDA hopes to bring reuse to the Web development community without resorting to the form of a framework. The most prevalent reuse paradigm found for the JavaScript language takes the form of object and API reuse. Efforts such as those put forth by the JSAN [31] team aims to further promote this reuse paradigm for the JavaScript language. Their approach

Figure 6. From left to right: Dept. of Human Services, Pittsburgh A+ Schools, Venture Outdoors

7.2 Substitution The system also included a mapping control. As shown in Figure 9, the blueprint for the mapping control described a domain composed of four atomic infotrons: an image element, a server side CGI interface to the Java OpenMap, a mercator projector, and a control logic that held them all together.

Figure 7. First-level breakdown of the “Tabbed View” encoding organizational contact, programs, and facilities information Given such a view, the individual devices that took on the task of encoding the respective information types were built first and then were composed together to create a blueprint as shown in Figure 8. As features were added, developers were able to work from top to bottom as well. For example, when a new tool was required to allow users to page through a heterogeneous array of views, a prototype was first built to test for the usability of the proposed interaction pattern. The implementation of the prototype involved building a fully functional paging tool that allowed paging through an array of JPEG image elements. The JPEG images were placeholders for the heterogeneous views. When the usability test was complete, and tweaks were made to the tool, substituting the JPEG image elements with the actual views required very little effort. Given that the system was being built out of loosely coupled black boxes, device boundaries were relatively clear in most cases. This allowed developers to work in parallel and tackle the process of integration in a streamlined fashion. When an instance of misbehaving infotrons was found, it was possible to isolate and fix the problem locally without requiring major changes to the rest of the system.

Figure 9. Blueprint of the “Java OpenMap View” This blueprint, called the “Java OpenMap View”, was then included in a parent blueprint called the “Map View”. The “Map View” blueprint provided the navigational controls as shown in Figure 10. However, when Google Maps became publicly available, we decided to forgo the dependency on Java OpenMap and substitute it with Google Maps. The Google Maps API was first wrapped in a blueprint so that it can run as an infotron and partake in our message-passing infrastructure. The terminal interface to the “Google Maps View” was made to be compatible with the “Java OpenMap View.” This ensured that the substitution required no change to the system, as shown in Figure 11.

Figure 10. “Java OpenMap View” encapsulated within the "Map View” that contains the navigation controls Figure 8. Simplified blueprint of the “Tabbed View”

ended up with close to 200 infotrons being loaded right off the bat. Furthermore, none of the optimization techniques mentioned in sections 4 and 5 was implemented until after the project. Therefore, a lot of time was spent upfront loading JavaScript that was not necessary for the bootstrap process. All these issues contributed to the initial page load time of 5 seconds or more even on high-bandwidth LAN. In future projects we will be more careful about where we draw the boundary of an atomic infotron, and also make full use of on-demand script loading where appropriate. Further issues concerning bandwidth rose when developers began using numerous domain blueprints that required immediate loading. These domain blueprints were built to keep the developers’ sanity intact by allowing them to maintain system complexity at a tractable level and to promote reuse.

Figure 11. “Java OpenMap View” substituted with “Google Maps View”

7.3 Reuse and Extension Given that the three Web-based systems shared very similar interfaces, it was no surprise that reuse was prevalent. A good example of both reuse and extension involves the use of the “hover” infotron. When we were unsatisfied with the hover text provided by the “title” attribute found in HTML, a new requirement to extend the system with more flexible hover functionality was introduced. The “hover” blueprint was a blueprint of a domain that consisted of a text element, a few image elements, and logic that allowed the customization of its behavior. In the simplest case, adding hover information was merely a matter of wiring the “user_event” terminal of the visual target to the terminal on the “hover” infotron that toggled its visibility. Given its loosely coupled nature, the “hover” infotron became the most widely reused infotron and helped showcase the extensibility of the system.

7.4 Polymorphic Views It was also interesting to witness a form of visual polymorphism in the course of designing the system. In other words, the development of views that were able to visualize the same data in multiple ways came naturally as part of the architecture. Once the exchange format between the data infotron and the view infotron was standardized, allowing the switch between a columnar representation of the data and a geographical map representation of the data evolved naturally from the system.

7.5 Post-Mortem The use of standard Web technologies such as HTML and JavaScript allowed us to apply conventional strategies in optimizing the deployment of the Web-based systems. For example, encoding the HTTP response in gzip format and reducing the HTTP request/response roundtrip by consolidating multiple external JavaScript source files into one were ways to help reduce the network payload considerably. However, there was still much concern about performance due to the fact that we had set the granularity of the infotrons very low. This can be classified as a classic dataflow problem where we had turned the tiniest of things (such as a single div with text) into atomic infotrons. As a result, the front page of the application

However, as domain blueprints are built as separate HTML pages in JDA, they required an additional HTTP roundtrip. Therefore, as more and more nested domain blueprints were being constructed one after another, latency and bandwidth problems started to creep up again. Our current belief is that HTML-based domain blueprints should be used only when they may be constructed lazily. However, there are most certainly cases when domains must be constructed proactively. As a matter of fact, it may not only make sense, but also be vital to our goal of largescale reuse. For those cases, we imagine providing a compilation service that runs on the server side to flatten the nested hierarchy of domain blueprints. Therefore, instead of sequentially constructing multiple domain blueprints as separate HTML pages, a single HTML file can be delivered, thus reducing the effect of the network on the initial load time of the system. On a related note, as we began developing domain blueprints that were heavy in images, we were faced with another form of performance bottleneck. The problem was that Star could only run after the Web browser had triggered the “onload” event. This is due to a browser limitation that a crucial method named getElementById works only after the “onload” event had been triggered. However, the default behavior of the Web browser is to trigger the “onload” handler after all the images on a given page have been fully loaded. As the number of images displayed on a given page increased, the time it took for the “onload” handler to be triggered was extended. The most recent solution to this problem involves the use of the “DOMContentLoaded” event and related workarounds. Unfortunately, this technique was not widely known at the time of the project. Given that latency was a hot topic of the project, it would be interesting to see how well large-scale reuse will fare when taken in the most literal sense. In other words, if a Web application were built completely from blueprints residing in third-party Web servers scattered throughout the World Wide Web, the time required to bootstrap could potentially be very large. Perhaps a way to remedy such situations is to take advantage of services such as Akamai or to always download a copy of the blueprint to the local Web server. One could also imagine automating this downloading by building a mechanism into the local Web server so that it knows what the blueprint’s true URL is. Then when the blueprint is first requested, it will generate a cache miss resulting in a lazy retrieval of the blueprint. All subsequent requests for the same blueprint can then be served from the local Web server.

On the workflow front, the clean separation of UI and its control logic was well received by the visual designers and the developers alike. The feedback was very positive not merely because it allowed them to work without becoming one another’s bottleneck, but also because it gave them common ground on which to base their communications. Although there were certainly learning curves associated with adopting a dataflow approach to system implementation, developers were generally pleased with the environment. It was especially rewarding when developers were heard uttering the phrase, “I love it when I hook things up, and it just works!”

8. Future Work Experimentation with our proposed architecture shows promise for large-scale reuse and also highlights the benefits of adopting the specific architecture and style of design. However, there is still a lot of work to be done. First, the aforementioned compilation service seems crucial to allow reuse to move beyond the granularity of a single JavaScript infotron. Such activity can become integrated into the Web server so that compilation happens “just-in-time,” and cached results of the compilation can be used until a new release happens. Second, JS-Star can certainly be improved--better use of the JavaScript language, more optimal memory usage, and more useful patterns for asynchronous programming are areas that should be addressed. At present, it is unclear if JavaScript can provide the means to issue blocking calls that can trigger preemptive or even cooperative scheduling. However, if this becomes possible, it would definitely help to provide a more intuitive synchronous programming pattern without affecting the asynchrony of the system. Finally, the tools used to create blueprints can be improved further to raise the productivity of developers. Dataflow architecture is often associated with its intuitive visualizations [53]. We believe it’s conceivable that an intuitive visual programming environment can be created for this paradigm to allow developers to assemble the infotrons using directmanipulation techniques. This may make way not only for developers versed in HTML to take advantage of the JDA architecture, but also for novice users who do not have any HTML skills to do so as well. The potential for large-scale reuse on the Web would most certainly benefit from such an endeavor. Moreover, there’s always the issue of security. In a truly largescale reuse case, without any layer of security, it can be dangerous to blindly load blueprints across the World Wide Web. Beyond the boundaries of the Web browser, there are parallel efforts experimenting with reference implementations of IDA for the Java, C, and Python languages. The efforts also include providing a bridge between these different language realms without breaking the dataflow paradigm. The add-on to JDA called the DOM-Renderer mentioned in section 4.6.2 can also use improvements in performance and efficiency. We believe it’s important to invest time in improving this add-on, as the high amount of reuse found in the three Webbased systems is greatly owed to this add-on. We believe that the spirit of the Web resides in promoting standards and interoperability. It is our hope that an architecture

such as JDA can aid in providing tractability, extensibility, and reusability to engineering Web-based systems. As JDA does not pretend to be a kitchen-sink framework, but rather an architectural style of design, it is our hope that others working in the field of Web engineering can more easily adopt the standards put forth by JDA to make truly large-scale reuse on the Web a reality.

9. References [1] http://www.e-janco.com/browser.htm [2] Damith C. Rajapakse, Stan Jarzabek. An Investigation of Cloning in Web Applications. In Proceedings of WWW’05 (Chiba, Japan) ACM Press 924-925

[3] [4] [5] [6]

http://backbase.com http://dojotoolkit.org http://developer.yahoo.net/yui/ http://en.wikipedia.org/wiki/Mashup_%28web_application_h ybrid%29

[7] Shirley V. Browne, James W. Moore, Reuse Library Interoperability and the World Wide Web. In Proceedings of SIGSOFT’97 (Boston, MA, 1997) ACM Press 182-189

[8] http://dynapi.sf.net [9] Seung Chan Lim, JavaScript Devices Architecture: Building Extensible Rich Web Applications Using Black Box Composition. In Proceedings of WTAS’05 (Calgary, AB, Canada) ACTA Press 1-6

[10] Gamma, E., Helm, R., Johnson R., Vlissides J., Design Patterns: Elements of Reusable Object-Oriented Software. Addisson Wesely. 1994

[11] Software Reuse and Re-engineering http://frakes.cs.vt.edu/5744pdf/reuse.pdf

[12] Jones M., Rashid R., Mach and Matchmaker: Kernel and Language Support for Object-Oriented Distributed Systems. In Proceedings of OOPSLA’86 (Portland, Oregon, 1986) ACM Press 67-77

[13] Agha Gul, Foundational Issues in Concurrent Computing. In Proceedings of the SIGPLAN’88 (San Diego, CA, 1988)

[14] Hewitt C., Bishop P., Greif I., Smith. B., Matson T., Steiger R., Actor Induction and Meta-Evaluation. In Proceedings of SIGPLAN’73 (Boston, MA, 1973) ACM Press, 153-168

[15] Krishnamurth S., Fellesen M., Toward a Formal Theory of Extensible Software. In Proceedings of SIGSOFT’98 (lake Buena Vista, FL, 1998) ACM Press, 88-98

[16] Standardization in Technology-Based Markets Gregory Tassey Senior Economist National Institute of Standards and Technology June 1999

[17] Szyperski C., Gruntz, D., and Murer, S. Component Software: Beyond Object-Oriented Programming. ACM Press, Addison Wesley 2002

[18] Ward, S. A. and Halstead, R. H. 1980. A Syntactic Theory of Message Passing. J. ACM 27, 2 (Apr. 1980), 365-383.

[19] Schlichting, R. D. and Schneider, F. B. 1982. Understanding and using asynchronous message passing (Preliminary Version). In Proceedings of the First ACM SIGACTSIGOPS Symposium on Principles of Distributed Computing

(Ottawa, Canada, August 18 - 20, 1982). PODC '82. ACM Press, New York, NY, 141-147.

[20] http://www.microsoft.com/com/ [21] http://www.corba.org/ [22] Silc, J., Robic, B., and Ungerer, T. 1998. Asynchrony in parallel computing: from dataflow to multithreading. Parallel Distrib. Comput. Pract. 1, 1, 3—30

[23] Simon, Herbert. The Sciences of the Artificial. MIT Press 1998

[24] Raymond, Eric The Art of UNIX Programming. Addison Wesley. 2003

[25] DesJardins, R. 1981. Overview and status of the ISO reference model of open systems interconnection. SIGCOMM Comput. Commun. Rev. 11, 2 (Apr. 1981), 1014.

[26] Lee, B. and Hurson, A. R. 1993. Issues in dataflow computing. Adv. in Comput. 37, 285--333.

[27] Sarkar V., Hennessy J., Partitioning Parallel Programs for Macro-Dataflow. In Proceedings of LFP’86 (Cambridge, MA, 1986) ACM Press 202-211

[28] http://www.sun.com/software/jxta/ [29] The Open Group, DCE 1.1: Remote Procedure Call. CAE Specification C706, The Open Group, Cambridge, MA 1997

[30] Friedrich Steinmann, Thomas Kühne, Coding for the Code. ACM Queue, Vol. 3 No. 10. ACM, Dec/Jan 2005-6.

[31] http://openjsan.org/ [32] http://bennolan.com/behaviour/ [33] http://www.xmlrpc.com/ [34] http://www.json.org/ [35] Dahofy E. M., Hoek A., Taylor R. N., An Infrastructure for the Rapid Development of XML-Based Architecture Description Language. In Proceedings of ICSE’02 (Orlando, FL, 2002) ACM Press, 266-276.

[36] http://djslim.com/hrb/ [37] http://www.xml.com/pub/a/2005/12/21/json-dynamic-scripttag.html

[38] http://java.sun.com/products/ejb/ [39] http://www.w3.org/2002/ws/

[40] Garlan D., Monroe R., and Wile D. ACME: An Architecture Description Interchange Language Conger. In Proceedings of CASCON’97 (Toronto, Ontario, Canada, 1997) IBM Press, 7-21

[41] Dahofy E. M., Hoek A., Taylor R. N., An Infrastructure for the Rapid Development of XML-Based Architecture Description Language. In Proceedings of ICSE’02 (Orlando, FL, 2002) ACM Press, 266-276.

[42] Martin Gaedke, Jorn Rehse, Supporting compositional reuse in component-based Web engineering. In proceedings of SIGAPP’00 (Como, Italy, 2000) ACM Press, 927-933

[43] DeRemer F., Kron H., Programming-in-the-Large Versus Programming-in-the-Small. In Proceedings of ICRS’75 (Los Angeles, CA, 1975) ACM Press, 114-121

[44] Arvind, Kathail, V., Pingali, K. A datafiow architecture with tagged tokens. Tech. Memo. 174, Laboratory for Computer Science, MIT, Cambridge, Mass. 1983

[45] Daivs, A. L., Keller, R.M. Data Flow Program Graphs. IEEE Computer 15, 2, 26–41. 1982.

[46] Dennis, J. B., Misunas, D. P., A Preliminary Architecture for a Basic Data-Flow Processor. In Proceedings of the Second Annual Symposium on Computer Architecture. 126–132. 1975.

[47] Karp, R., Miller, R., Properties of a Model for Parallel Computations: Determinacy, Termination, Queueing. SIAM J. 14, 1390–1411. 1966

[48] http://bindows.net/ [49] http://beta.asp.net/default.aspx?tabindex=7&tabid=47 [50] http://prototype.conio.net/ [51] http://www.maya.com/web/what/papers/maya_trillion_node_ network.pdf

[52] http://www.maya.com/web/what/papers/maya_universal_dat abase.pdf

[53] Johnston, W. M., Hanna, J. P., and Millar, R. J. 2004. Advances in dataflow programming languages. ACM Comput. Surv. 36, 1 (Mar. 2004), 1-34.

Suggest Documents