James Robinson 84690ebeab Add tracing service and make the shell+sky_viewer+services talk to it
This adds a tracing service that can aggregate tracing data from
multiple sources and write a json file out to disk that trace-viewer can
understand. This also teaches the shell, sky_viewer, and various other
services how to register themselves with the tracing service and provide
tracing data on demand. Finally, this teaches the skydb prompt to tell
the tracing service to start/stop tracing when the 'trace' command is
issued.

The tracing service exposes two APIs, a collector interface and a
coordinator interface. The collector interface allows different entities
to register themselves as being capable of producing tracing data. The
coordinator interface allows asking the service to collect data from
all registered sources and flushing the collected data to disk.

The service keeps track of all open connections to registered sources
and broadcasts a request for data whenever the coordinator's Start
method is called, then aggregates all data send back into a single
trace file. In this patch, the tracing service simply gives all sources
1 second to return data then flushes to disk. Ideally it would keep
track of how many requests it sent out and give each source a certain
amount of time to respond but this is simple and works for most cases.

The tracing service can talk to any source that is capable of producing
data that the trace-viewer can handle, which is a broad set, but in
practice many programs will want to use //base/debug's tracing to
produce trace data. This adds code at //mojo/common:tracing_impl that
registers a collector hooked up to //base/debug's tracing system. This
can be dropped in to the mojo::ApplicationDelegate::Initialize()
implementation for most services and applications to easily enable
base tracing. Programs that don't use //base, or that want to register
additional data sources that can talk to trace viewer (perhaps providing
data that's more easily available from another thread, say) may want
to create additional connections to the tracing service.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/769963004
2014-12-01 16:31:03 -08:00
2014-11-26 13:54:14 -05:00
2014-12-01 16:08:07 -08:00

Sky

Sky is an experiment in building a UI framework for Mojo. The approach we're exploring is to create a layered framework based around a retained hierarchy of semantic elements. We're experimenting with different ideas and exploring various approaches, many of which won't work and will need to be discarded, but, if we're lucky, some of which might turn out to be useful.

Sky has three layers, each of which also adds progressively more opinion. At the lowest layer, Sky contains a rendering engine that parses markup, executes script, and applies styling information. Layered above the engine is a collection of components that define the interactive behavior of a suite of widgets, such as input fields, buttons, and menus. Above the widget layer is a theme layer that gives each widget a concrete visual and interactive design.

Elements

The Sky engine contains a handful of primitive elements and the tools with which to create custom elements. The following elements are built into the engine:

  • script: Executes script
  • style: Defines style rules
  • import: Loads a module
  • iframe: Embeds another Mojo application
  • template: Captures descendants for use as a template
  • content: Visually projects descendents of the shadow host
  • shadow: Visually projects older shadow roots of the shadow host
  • img: Displays an image
  • div: Neutral element for hooking styles in shadow trees
  • span: Neutral element for hooking styles in shadow trees
  • a: Links to another Mojo application
  • title: Briefly describes the current application state to the user
  • t: Preserve whitespace (by default, whitespace nodes are dropped)
  • error: Represents a parse error

Additional Elements

In addition to the built-in elements, frameworks and applications can define custom elements. The Sky framework contains a number of general-purpose elements, including input, button, menu, toolbar, video, and dialog. However, developers are free to implement their own input fields, buttons, menus, toolbars, videos, or dialogs with access to all the same engine features as the frame because the framework does not occupy a privileged position in Sky.

Custom Layout

TODO: Describe the approach for customizing layout.

Custom Painting

TODO: Describe the approach for customizing painting.

Modules

Sky applications consist of a collection of modules. Each module can describe its dependencies, register custom elements, and export objects for use in other modules.

Below is a sketch of a typical module. The first import element imports the Sky framework, which defines the sky-element element. This module then uses sky-element to define another element, my-element. The second import element imports another module and gives it the name foo within this module. For example, the AnnualReport constructor uses the BalanceSheet class exported by that module.

SKY MODULE
<import src=”/sky/framework” />
<import src=”/another/module.sky” as=”foo” />
<sky-element name=”my-element”>
class extends SkyElement {
  constructor () {
    this.addEventListener('click', (event) => this.updateTime());
    this.shadowRoot.appendChild('Click to show the time');
  }
  updateTime() {
    this.shadowRoot.firstChild.replaceWith(new Date());
  }
}
</sky-element>
<script>
class AnnualReport {
  constructor(bar) {
    this.sheet = new foo.BalanceSheet(bar);
  }
  frobinate() {
    this.sheet.balance();
  }
}

function mult(x, y) {
  return x * y;
}

function multiplyByTwo(x) {
  return mult(x, 2);
}

module.exports = {
  AnnualReport: AnnualReport,
  multiplyByTwo: multiplyByTwo,
};
</script>

The script definitions are local to each module and cannot be referenced by other modules unless exported. For example, the mult function is private to this module whereas the multiplyByTwo function can be used by other modules because it is exported. Similarly, this module exports the AnnualReport class.

Services

Sky applications can access Mojo services and can provide services to other Mojo applications. For example, Sky applications can access the network using Mojo's network_service. Typically, however, Sky applications access services via frameworks that provide idiomatic interfaces to the underlying Mojo services. These idiomatic interfaces are layered on top of the underlying Mojo service, and developers are free to use the underlying service directly.

As an example, the following is a sketch of a module that wraps Mojo's network_service in a simpler functional interface:

SKY MODULE
<import src=”mojo:shell” as=”shell” />
<import src="/mojo/network/network_service.mojom.sky" as="net" />
<import src="/mojo/network/url_loader.mojom.sky" as="loader" />
<script>
module.exports = function fetch(url) {
  return new Promise(function(resolve, reject) {
    var networkService = shell.connectToService(
        "mojo:network_service", net.NetworkService);
    var request = new loader.URLRequest({
        url: url, method: "GET", auto_follow_redirects: true});
    var urlLoader = networkService.createURLLoader();
    urlLoader.start(request).then(function(response) {
      if (response.status_code == 200)
        resolve(response.body);
      else
        reject(response);
    });
  };
};
</script>

Notice that the shell module is built-in and provides access to the underlying Mojo fabric but the net and loader modules run inside Sky and encode and decode messages sent over Mojo pipes.

Specifications

We're documenting Sky with a set of technical specifications that define precisely the behavior of the engine. Currently both the implementation and the specification are in flux, but hopefully they'll converge over time.

Contributing

Instructions for building and testing Sky are contained in HACKING.md. For coordination, we use the #mojo IRC channel on Freenode.

History

Sky started from the Blink codebase r181355: http://blink.lc/blink/tree/?id=086acdd04cbe6fcb89b2fc6bd438fb8819a26776

Languages
Dart 75%
C++ 16.5%
Objective-C++ 2.9%
Java 2.8%
Objective-C 0.7%
Other 1.9%