One of the goals of this cycle is to decrease application startup times on the Ubuntu phone images. Part of my work there was to look at the time taken by Upstart App Launch in initializing the environment for the application. One of the tricky parts of measuring the performance of initialization is that it contains several small utilities and scripts that span multiple Upstart jobs. It's hard to get a probe inside the system to determine what is going on without seriously disrupting it.
For measuring everything together I decided to use LTTng which loads a small kernel module that records tracepoints submitted by userspace programs using the userspace tracer library. This works really well for Upstart App Launch because we can add tracepoints to each tool, and see the aggregate results.
To setup your Ubuntu Touch device to get some results you'll need to make the image writable and add a couple of packages:
$ sudo touch /userdata/.writable_image $ sudo reboot # Let it reboot $ sudo apt-get update $ sudo apt-get install lttng-modules-dkms lttng-tools $ sudo reboot # Rebooting again, shouldn't need to, but eh, let's be sure
You then need to setup the Upstart App Launch environment variable to get it registering with LTTng:
$ initctl set-env --global LTTNG_UST_REGISTER_TIMEOUT=-1
Then you need to setup a LTTng session to run your test. (NOTE: this configuration allows all events through, but you can easily add event filters if that makes sense for your task)
$ lttng create browser-start $ lttng enable-event -u -a $ lttng start
To get the Upstart starting events from DBus into LTTng:
$ dbus-monitor --profile sender=com.ubuntu.Upstart,member=EventEmitted,arg0=starting | ./dbus_monitor_lttng_bridge
And at last we can run our test, in this case starting the webbrowser once from not running and once to change URLs:
$ url-dispatcher http://ubuntu.com # wait for start $ url-dispatcher http://canonical.com
And then shut things down:
$ lttng stop $ lttng destroy browser-start
This then creates a set of traces in your home directory. I pulled them over to my laptop to look at them, thougth you could analyze them on the device. For complex traces there are more complex tools that are available, but for what I needed babletrace was enough. All of this contributed to a set of results that we are no using to optimize upstart-app-launch to make applications start faster!
posted on Mon, 16 Dec 2013 at 13:17 | permanent link
When looking at Upstart it comes off as very simple. Almost too much so. It's just events. And jobs that take those events. And not much else. You're so used to configuring every last detail of a system to ensure that it's tightly tuned for every possible scenario, certainly you need more tools than just events! When you let go of that preconception and really start to understand it, you realize that events are not only enough, but they're exactly what you need.
One might have thought – as at first I certainly did – that if the rules for a program were simple then this would mean that its behavior must also be correspondingly simple. For our everyday experience in building things tends to give us the intuition that creating complexity is somehow difficult, and requires rules or plans that are themselves complex. But the pivotal discovery that I made some eighteen years ago is that in the world of programs such intuition is not even close to correct. — Stephen Wolfram, A New Kind of Science.
And so we take these simple jobs that we've built and we start to build a system. They each just wait on a set of events, and some emit events as they go along, and the system starts to take form. But where are our initialization phases and guarantees and complex dependencies? (writing code to solve them is fun!) They still exist, but as an emergent behavior of the system. Let's look at Graphviz diagram of the Ubuntu Saucy system init:
(Graphviz | Full SVG)
Without zooming in and just looking at the shapes that emerge you start to see a natural grouping of the jobs. And there are stages of the boot. There are types of jobs that are gathered together. There'd be even more if initctl2dot could break down the runlevel job into its various values. What we see is a the complex boot of a modern operating system broken down into pieces for analysis. What we see is a model of the behavior of the system, but that model is the only place that the complexity actually exists, it becomes the emergent behavior of the system. And that, that is why Upstart can be so simple and yet be powerful enough to boot a modern Linux system.
posted on Sun, 04 Aug 2013 at 00:06 | permanent link
I love BAMF, may it die a peaceful death. BAMF was always stuck trying to solve an unsolvable problem, trying to recreate information and associations that had been lost through the X11 protocol and general fuzziness about what should happen. BAMF then had to handle a wide variety of corner cases and try to bring things back into a situation of sanity. And I loved BAMF because I didn't have to do that myself, BAMF did it, and all of its clients just got sanity. We knew when starting another display system we didn't want another BAMF.
With Mir there is a closer tie between applications as a whole and their windows. When an application asks for a session it specifies who it is, then Unity can make sure it understands who it is, and gets a chance to veto the connection. This means that Unity can check on the status of who the app says it is before it gets any windows and can track that directly throughout the application session. To do this we're using what we call the "Application ID", which for most apps you have today is the name of their desktop file (e.g., "inkscape", "gedit").
Let's look at an overly verbose message sequence diagram to see how this works. Note: all of the columns on here aren't separate processes, the diagram is made to explain this idea, not to represent the system architecture.
(svg | msc)
What we can see here is that because Upstart is doing process tracking, and making sure it knows the state of the application, Unity have have assurances of the application's name and existence. It then can work with Mir to block applications that do have proper configurations and can't be matched well. 100% matching, by design.
posted on Wed, 24 Jul 2013 at 11:55 | permanent link
One of the design goals of Unity was to have an Application-centric user experience. Components like the Launcher consolidate all of the windows into a single icon instead of a set like the GNOME 2 panel. Nothing else in Ubuntu thinks about applications in this way making it a difficult user experience to create. X11 worries about windows. DBus worries about connections. The kernel focuses on PIDs. None of these were focused on applications, just parts of applications. We created the BAMF Application Matching Framework (BAMF) to try and consolidate these, and while it has done a heroic job, its task is simply impossible. We need to push this concept lower into the stack.
First we looked at the display server and started thinking about how it could be more application centric. That effort resulted in Mir. Mir gets connections from applications and manages their associated windows together. They can have multiple windows, but they always get tracked back to the application that created them. Unity can then always associate and manage them together, as an application, without any trickery.
Application confinement also provides another piece of this puzzle. It creates a unified set of security policies for the application independent of how many submodules or processes exist for it. One cache directory, set of settings and policies follow the application around. Apparmor provides a consistent and flexible way of managing the policies along with the security that we need to keep users safe.
To start to look at the process management aspect of this I started talking to James Hunt about using Upstart, our process manager in Ubuntu. Working together we came up with a small little upstart user session job that can start and stop applications, and also track them. I've pushed the first versions of that to a test repository in Launchpad. What this script provides is the simple semantics of doing:
to manage the application. Of course, the application lifecycle is also important, but Upstart provides us an guaranteed way of making sure the application stops at the end of the session.$ start application APP_ID=gedit $ stop application APP_ID=gedit
Upstart can also help us to guarantee application uniqueness. If you try and start an application twice you get this:
This way we can ensure that a single icon on the launcher associates to a set of processes, managed by the process manager itself. In the past libraries like libunique have accomplished this using DBus name registration. Which, for the most part, works. Using DBus registration relies on well behaving applications, which basically guarantee their own uniqueness. By using Upstart we can have misbehaving applications, and still guarantee their uniqueness for the Unity to show the user.$ start application APP_ID=inkscape application (inkscape) start/running, process 30878 $ start application APP_ID=inkscape start: Job is already running: application (inkscape)
We're just getting started on getting this setup and working. The schedule isn't yet final for vUDS next week, but I imagine we'll get a session for it. Come and join in and help us define this feature if it interests you.
posted on Tue, 07 May 2013 at 08:16 | permanent link
For a while I've had a little project for debugging the desktop. Basically it starts tracking all of the DBus events on the user session startup so that you can figure out what's going on. This is especially an issue for indicators, where they're started at login, and sometimes it can be hard to track what is happening.
Previously it was pretty hard to inject into the startup of the session. Getting in the middle of building a very long command line was risky and pretty fragile. Not proud of what I had to do. Now that I have Upstart user session running, I took the opportunity port this debugging script over to Upstart.
Now I have this one simple configuration file that can be dropped in /usr/share/upstart/sessions and gets started immediately after dbus:
description "Bustle Boot Log" author "Ted Gould
" start on started dbus stop on desktop-end script rm -f ~/.cache/bustle-boot-log/boot-log.bustle mkdir -p ~/.cache/bustle-boot-log/ timeout -s INT 30 bustle-pcap --session ~/.cache/bustle-boot-log/boot-log.bustle & end script
The beauty of this is that I can inject this small little script in, and have Upstart figure out all the startup mess. I also have minimal impact on the natural desktop boot which is critcial for testing. Simple things to make debugging easier.
posted on Tue, 30 Apr 2013 at 14:59 | permanent link
I've started to prototype and lay the foundations for the indicators to use the Upstart User Sessions. It's an exciting change to our desktop foundations, and while it's still very fresh, I think it's important to start understanding what it can do for us. For right now you're going to need a patch to Unity and a patch to indicator-network to even get anything working, not recommended for trying at home.
Previously for indicators the way that they've worked is that a small loadable module was loaded by the panel service that had indicator specific UI in it. That plugin also took care of the responsibility to restart the indicator backend, respawning it if it crashed. While this works and it has created a robust desktop (most people don't notice when their indicator backends crash) it has had some downsides. For one, it makes it difficult to build and test new backends as you pretty much have to restart Unity to stop the previous service from getting respawned. Also all the debugging messages end up coming under the DBus process in ~/.xsession-errors because we were using DBus activation to start them.
With upstart user sessions we're now getting a lot more power and flexibility in managing the jobs in the user session, it makes sense that indicators would start to use it to control the backend services. This comes with a set of advantages.
The first one is that there is better developer control of the state of the process. It's really easy to start and stop the service:
$ stop indicator-networkand the ever exciting:
$ start indicator-network
$ restart indicator-networkAll of these ensure that the same commands are run each time in a recreatable way. Plus give the user and/or developer full control.
Upstart also takes the output of each process and puts it into its own log file. So for our example here there is a ~/.cache/upstart/indicator-network.log that contains all of the junk that the backend spits out. While this is nice to just make xsession-errors cleaner, it also means that we can have a really nice apport-hook to pick up that file. Hopefully this will lead to easier debugging of every indicator backend bug because they'll have more focused information on what the issue is. You can also file general bugs with ubuntu-bug indicator-network and get that same information attached.
In the future we'll also be able to do fine tuned job control using external events. So we could have the indicator network backend not start if you don't have any networking devices, but startup as soon as you plug in that USB cellular modem. We're not there yet, but I'm excited that we'll be able to reduce the memory and CPU footprint on devices that don't have all the features of higher end devices, scaling as the features are required.
Those that know me know that I love diagrams and visualizations, and so I'll have to real quickly say that I'm excited about being able to map our desktop startup using intlctl2dot. This gives a Graphviz visualization of startup and how things will interact. I expect this to be a critical debugging tool in the future.
What's next? Getting all the indicators over to the branch new Saucy world. We also want to get application indicators using a similar scheme and get a fast responsive desktop. Hope to have a blog post or two on that in the near future.
posted on Thu, 25 Apr 2013 at 12:30 | permanent link
Going to sleep last night I started thinking about inflation, which meant that I got to sleep later than I'd wished, but it also lead to some interesting thoughts about where the US economy is currently. Popularly inflation is considered bad, or something that needs to be controlled through monetary policy. And that we have. In the US we've seen record low inflation rates, to the point where we've lowered interest rates to where it's practically a useless lever on the economy. It seems to me that we need higher inflation.
Inflation powers the creative destruction that makes capitalism work as an economic system. For value to increase relative to inflation we must reprice things, and they must continue to have more value to the people in the economy. If weak products just stick around, with their current value in tact, they effectively stagnate as they don't get ground under the treadmill of inflation. This is the evolutionary gauntlet that destroys those who are not fit to compete. Perhaps capitalism is driven less by an invisible hand and more an invisible treadmill.
We can as a country control inflation and increase it artificially through policy in government. Policy programs like farm and transportation subsidies ensure that food prices don't rise. Starting to remove many of these would force farmers to charge more, which in turn would effect derivatives like meat and dairy to raise prices, effectively pushing inflation into play.
The economy is an ecosystem of stored value, consumers and producers. By eliminating inflation as a mechanism inside that ecosystem we've allowed the balance to be shifted and created a system that is off balance. We should adopt legislative policies to increase inflation.
posted on Wed, 03 Apr 2013 at 09:33 | permanent link
As you might have noticed in the tablet information we've put some time and effort into imaging the next steps for the HUD. For the last few months I've been leading a team to bring that into a reality on the tablet.
One of the problems facing application developers on a device like a tablet is adding functionality without making the entire interface feel cluttered. We even made the problem harder by emphasizing a content focused strategy in our SDK. Where do you put controls? There are various tools including toolbars, but none of them scale to even a moderately complex application. With the power of today's devices ever increasing, it's clear that tablet applications are going to become more complex.
We could just tell application authors not to do it. Save that complexity for your desktop UI. But that wouldn't be convergence, that'd be creating silos for you applications to live in.
By using HUD we allow applications to expose rich functionality that is available to the user via search. Users can search through the actions exposed by the application to find the functionality that they need. We combine that with historical usage and recently used items to take into account what functionality the user uses in the application. It's the rich functionality of your application, customized for the individual user.
One of the things we realized early in the HUD 2.0 efforts is that we can no longer just passively take data from applications and make things better. We needed to go beyond menu sucking to having applications actively targeting the HUD. We're building HUD functionality directly into the SDK making it easily available for application developers to add actions that are visible in the HUD.
By providing a way for applications to export both actions and their descriptions to the HUD directly we can make that interaction much richer. We can do things like get the keywords pragmatically so that they're included next to the original item definitions. This also allows us to define actions that have additional properties that can be adjusted with UI elements, we're calling these parameterized actions.
Parameterized actions provide a way for applications to create a small autogenerated UI for simple settings and items that can be quick to edit. Let's be clear, autogenerated UI's aren't the best UI's, but if done right can be attractive and effective. We aim to do it right. Hopefully your application has a primary UI that is beautiful and tailored for its specific task that is then supplemented with additional settings and actions in the HUD, parameterized actions are no different there.
Currently in the code we only have support for sliders of integer percentages. That's pretty limiting. We plan on expanding that to most of the base widgets in the toolkit.
While talking to yourself makes you seem crazy, talking to your tablet is just cool. With the HUD we realized that we had a relatively small data set, and so it would be possible to get reasonable voice recognition using the resources available in the device. That makes a great way to interact with an application, keyboards are chunky on any handheld device (but needed for when you're supposed to be paying attention to the person talking) and voice makes interacting much more fluid.
We built the voice feature around two different Open Source voice engines: Pocket Sphinx and Julius. While we started with Pocket Sphinx we weren't entirely happy with it's performance, and found Julius to start faster and provide better results. Unfortunately Julius is licensed with the 4-clause BSD license, putting it in multiverse and making it so that we can't link to it in the Ubuntu archive version of HUD. We're looking at ways to make it so that people who do want to install it from multiverse can easily use Julius, but what we'd really like is to make the Pocket Sphinx support really great. It's something we'd love help with. We're not voice experts, but some of you might be, let's make the distributable free software solution the best solution.
When we did user testing of the first version of the HUD one of the biggest problems users had was composing a search in the terms used in the applications. It turns out users search for "Send E-mail" instead of "Compose New Message". I'm sure there are even some people who want to "Clear History" but others want to "Delete" it. To help this situation we've introduced keywords that can be added as a sidecar file to legacy applications, and defined directly for libhud exported actions. These can then be searched for as well, increasing the ability of application authors to provide different ways to express the same action.
One of the issues that the HUD has in general is discoverability. How do I know that this cool new app I downloaded can do color balancing? Does every app need to run a Superbowl ad to make consumers realize their features? We've got some ideas, but come and share yours on the unity-design mailing list.
While the source is published, we still don't have beautiful documentation and developer help out there yet. We're working on it. You're welcome to look at the source code, or just hang tight, I'll have another blog post soon.
posted on Thu, 21 Feb 2013 at 13:41 | permanent link
I'm getting ahead of the curve and calling it, there will be a Cloud 2.0. I know, shocking, but I think that there are some interesting changes afoot that will lead to a change in cloud deployments. Enough to justify the 2.0 tag. If you haven't read it yet, you should probably read my 2GB is enough for anyone post as it'll set the stage for what's going on here.
The key part about what happens in that post that relates to this one is that Internet companies will start having commercial relationships with telcos. They'll be paying for bandwidth, and they'll want to optimize their own costs. But before we can talk about 2.0 and how that optimization can happen, let's first define what 1.0 is.
There are a million definitions of what "cloud" is, and I'm not going attempt to clear up all the confusion or provide a comprehensive definition. That'd result in failure. But because of the confusion, I feel that we need a common thought to work from.
I'm going to go ahead and talk about Cloud 1.0 as the move from servers you own, to servers you rent and that you have no idea of the real physical location. Sure, you know that Amazon has different zones, but most people couldn't give you the mailing address for them. This is a transition from a world where you knew, and did a lot of planning around your hardware. If you thought you were going to have 10x as many customers next month, you're already behind on ordering and deployment. Today, there's no reason to care about that except to optimize your costs, which is something most startups aren't immediately concerned about. This is a good time to start a company who's main costs would have been servers.
From "where?" to "how many?"
At some point when your server setup starts to become super fluid, you start loosing track of how many servers you have. "Did we set up a second load balancer?" "Oh, I guess someone should figure that out." Today while you'd spend time to set up that second server (might be as easy as juju add-node) you still might not be entirely managing the exact numbers there.
In the future I think it is fair to say that there will be software managing the numbers for you, instead of allocating servers you'll specify a quality of service that you want to maintain (and this'll involve costs as well, maybe you can skip a daily backup during high shopping season). That change will make it so that the only thing that actually knows how many servers you have is your management software, and the person billing you for the time. But, you can still find out how many servers are out there, and you're still paying for individual machines. We can call this Cloud 1.5 in this discussion. It changes how you think about your setup, but in reality, your architecture is roughly the same.
Who cares how many servers
The problem even with that setup is that every customer to your service is still going across the Internet to get there. The edges of the network are getting faster at a more rapid rate than the backbone. This is most evident in the cell phone case where LTE speeds are making it so that rapid access to the cell tower is commonly available, but from the cell tower is a more difficult proposition. Cellular providers and high speed home networking providers are trying to combat this with bandwidth limits, but that's not a great solution for anyone. But it does lead to a unique relationship between Internet companies and cellular providers.
How does this effect clouds? Because of this existing relationship between the Internet services and the cellular network providers where they're working to avoiding bandwidth caps. Now they've got a relationship where they're both interested in reducing bandwidth costs. What would reduce bandwidth costs the most? It would be running the servers directly in the cell tower. Why not? With cloud platforms already setting up Internet companies running on virtualized environments, there's no reason those couldn't be expanded to the towers themselves.
It makes sense to me that these would be deployed on demand based on usage. There will always be a limitation of space and if Facebook is popular in Texas but MySpace in California, you'd want to only be using resources where it makes sense. Which means, at some level, deployment needs to be controlled by the cellular operator from images provided by the company providing the service. Which means, that as a company providing a service on the Internet, you might not even know how many of your servers are running. And that, not knowing how many servers you're actually running, that is Cloud 2.0.
posted on Mon, 03 Dec 2012 at 09:57 | permanent link
It's a bit after UDS Raring, but I'll blame my blog being broken on not writing the entry. It's fixed now and I wanted to take the opportunity to talk about a couple of themes that went on at UDS Raring that I'm excited about, but haven't gotten a lot of press generally.
Upstart in the user session. There is a bunch of work going on in 13.04 to start building the basis for a totally upstart based user session. Hopefully in 13.04 it'll get slightly underneath with some things changing, so the big change can happen safely in 13.10 and then be solid for 14.04. What this means in real user visible terms is that we can start to kill some of the long running processes that wait for events. Upstart gives use the ability to have more sophisticated job starting and stopping, and event listeners, so that you only have running the parts of the system you're using. The rest of the system can lay there... waiting... not sucking up resources.
Application containment (1, 2, 3, 4). There has always been an assumption in the Unix world that what happens in user space stays in user space, and that's okay, the system is secure. And this assumption has mostly worked out for us as really the number of applications running in user space has been fairly limited, and largely trusted. With things like the ability to easily publish applications in Software Center that barrier is getting lower, which is a really good thing, but it means we need to rethink security in that context. This work has been going on for a few UDSes, but at UDS-R I felt like it took a real turn to start being a workable plan that has a solution.
posted on Fri, 30 Nov 2012 at 14:50 | permanent link