This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 540507 - Investigate parallel activation of bundles
Summary: Investigate parallel activation of bundles
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 4.12 M3   Edit
Assignee: Thomas Watson CLA
QA Contact:
URL:
Whiteboard:
Keywords: noteworthy, plan
Depends on:
Blocks: 550136 550240
  Show dependency tree
 
Reported: 2018-10-26 09:22 EDT by Lars Vogel CLA
Modified: 2019-08-29 07:48 EDT (History)
8 users (show)

See Also:


Attachments
Recommendation improvents for activator (19.81 KB, patch)
2018-10-26 14:58 EDT, Mark Hoffmann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Lars Vogel CLA 2018-10-26 09:22:46 EDT
Currently the Equinox launcher calls Bundle.start() sequentially.

This missing the opportunity to run this activation in parallel, similar to Mickaels work for the JDT compiler. See Bug 531554.

See https://www.eclipse.org/lists/equinox-dev/msg08901.html especially:

-----
Activation of a bundle happens when the launcher calls Bundle.start(). You can certainly write a launcher that calls start() on many bundles concurrently from multiple threads.
-----

I suggest we investigate if we could allow parallel activation. This could potentially result in a significant startup improvement.

For example, here are the startup times of my bundles, running parts of this in parallel would be helpful:

Lars Vogel <lars.vogel@vogella.com>
	
11:20 AM (4 hours ago)
	
to General
Hi,

several committers and contributors asked about the tracing option in
Eclipse to measure startup time on EclipseCon.

As promised, I documented this and you find it here:
http://www.vogella.com/tutorials/EclipsePerformance/article.html#example-tracing-the-startup-time-of-plug-ins

Stuff we did to improve startup time in the past:
- Move Activator code to OSGi DS services
- Move blocking initialization code to Jobs
- Remove useless code if it exists

Here is the ranked output for my SDK + EGit + SonarLint + Asciidoctor
toolilng +e4 spies + Codemining based on the shell script from the
tutorial. The number at the beginning is the required time to start in
milliseconds, e.g., jdt.ui takes a bit more than half a second.

793 org.eclipse.egit.ui_5.0.0.201806131550-r
590 org.eclipse.jdt.ui_3.16.0.v20181019-1929
393 org.sonarlint.eclipse.ui_3.6.0.201806071228
314 org.sonarlint.eclipse.core_3.6.0.201806071228
278 org.eclipse.jdt.core_3.16.0.v20181023-1015
147 org.eclipse.ui.trace_1.1.200.v20180829-0709
144 org.eclipse.core.runtime_3.15.100.v20180907-0807
133 org.eclipse.update.configurator_3.4.100.v20180821-1913
121 org.eclipse.egit.core_5.0.0.201806131550-r
97 org.eclipse.core.resources_3.13.200.v20181016-1140
95 org.eclipse.ui.workbench_3.112.100.v20181023-1210
79 org.eclipse.equinox.simpleconfigurator_1.3.100.v20180827-1122
70 org.eclipse.osgi_3.13.200.v20180906-2135
68 org.eclipse.pde.ui_3.10.500.v20181023-0807
56 org.eclipse.equinox.console_1.3.200.v20181008-1820
52 org.eclipse.pde.core_3.12.200.v20181012-1153
49 org.eclipse.equinox.p2.ui.sdk.scheduler_1.4.100.v20180827-1122
43 org.eclipse.emf.common_2.15.0.v20180723-1316
43 org.eclipse.core.jobs_3.10.200.v20180912-1356
40 org.eclipse.jsch.core_1.3.200.v20180827-1041
36 org.eclipse.core.net_1.3.300.v20180827-1041
33 org.eclipse.core.contenttype_3.7.100.v20180817-1401
32 org.apache.felix.scr_2.0.14.v20180822-1822
30 org.eclipse.jdt.launching_3.11.100.v20181019-1948
27 org.eclipse.equinox.registry_3.8.200.v20181008-1820
26 org.eclipse.equinox.app_1.4.0.v20181009-1752
25 org.eclipse.equinox.preferences_3.7.200.v20180827-1235
24 org.eclipse.emf.ecore_2.15.0.v20180722-1159
22 org.apache.felix.gogo.runtime_1.1.0.v20180713-1646
20 org.eclipse.core.expressions_3.6.200.v20180817-1401
16 org.eclipse.debug.core_3.13.100.v20180910-0519
13 org.eclipse.team.ui_3.8.200.v20180827-1338
13 org.eclipse.equinox.p2.metadata.repository_1.3.100.v20180822-1302
13 org.eclipse.equinox.common_3.10.200.v20181021-1645
11 org.eclipse.team.core_3.8.300.v20180827-1041
11 org.eclipse.equinox.p2.reconciler.dropins_1.3.0.v20180921-1132
10 org.apache.felix.gogo.shell_1.1.0.v20180713-1646
9 org.eclipse.equinox.event_1.5.0.v20181008-1938
9 org.eclipse.compare_3.7.400.v20181019-1444
8 org.eclipse.e4.ui.workbench_1.8.0.v20181022-1348
8 org.apache.felix.gogo.command_1.0.2.v20170914-1324
7 org.sonarlint.eclipse.jdt_3.6.0.201806071228
5 org.eclipse.ltk.core.refactoring_3.9.100.v20180828-0626
5 org.eclipse.equinox.p2.repository_2.4.200.v20181005-1131
4 org.showshortcuts_1.0.1
4 org.eclipse.ui.editors_3.11.300.v20180914-0606
4 org.eclipse.equinox.p2.ui.sdk_1.1.100.v20180827-1122
3 org.eclipse.ui.workbench.texteditor_3.11.200.v20181017-0917
3 org.eclipse.equinox.p2.core_2.5.100.v20180822-1532
2 org.eclipse.ui.ide_3.14.200.v20181017-1322
2 org.eclipse.ui.cheatsheets_3.5.300.v20180823-1505
2 org.eclipse.ui_3.111.0.v20181017-1216
2 org.eclipse.tm.terminal.view.ui_4.5.0.201808290101
2 org.eclipse.ltk.ui.refactoring_3.9.200.v20180828-0626
2 org.eclipse.help_3.8.200.v20180821-0700
2 org.eclipse.equinox.p2.metadata_2.4.100.v20180822-1302
2 org.eclipse.e4.ui.workbench.swt_0.14.400.v20181022-1348
1 org.sonarlint.eclipse.m2e_3.6.0.201806071228
1 org.sonarlint.eclipse.cdt_3.6.0.201806071228
1 org.eclipse.wst.sse.ui_1.5.0.v201807252207
1 org.eclipse.ui.views.log_1.2.300.v20180827-1331
1 org.eclipse.ui.net_1.3.300.v20180827-1041
1 org.eclipse.ui.console_3.8.300.v20181019-1609
1 org.eclipse.pde.launching_3.7.300.v20180926-1404
1 org.eclipse.jdt.core.manipulation_1.11.0.v20181019-1929
1 org.eclipse.equinox.security_1.2.600.v20181022-1735
1 org.eclipse.equinox.p2.ui_2.5.300.v20180921-1019
1 org.eclipse.equinox.p2.operations_2.5.200.v20180928-1359
1 org.eclipse.equinox.p2.garbagecollector_1.1.100.v20180822-1302
1 org.eclipse.equinox.p2.engine_2.6.100.v20180822-1302
1 org.eclipse.equinox.p2.directorywatcher_1.2.100.v20180822-1302
1 org.eclipse.emf.ecore.xmi_2.15.0.v20180706-1146
1 org.eclipse.e4.tools.preference.spy_0.1.0.v20171212-1226
1 org.eclipse.core.filesystem_1.7.200.v20180828-0158
0 org.eclipse.ui.monitoring_1.1.300.v20180828-1350
0 org.eclipse.tips.ide_0.1.200.v20180821-0700
0 org.eclipse.jdt.codemining_1.0.0.201808270308
0 org.eclipse.egit.codemining_1.0.0.201808270308
0 org.eclipse.e4.ui.css.swt_0.13.300.v20180920-1522
0 org.eclipse.e4.tools.services_4.8.200.v20181022-1512
0 org.eclipse.e4.tools.bundle.spy_0.18.0.v20170601-1400
0 org.eclipse.core.filebuffers_3.6.300.v20180822-1339
0 org.eclipse.compare.core_3.6.300.v20180827-1041
Comment 1 Thomas Watson CLA 2018-10-26 10:01:42 EDT
This is not a launcher issue.  I think it could be a framework issue (if you are suggesting it be done as part of normal start-level increments for bundles).

I'm not convinced you will see much improvements and I think you may find it creates some potential for deadlocks on startup because of the way bundles in Eclipse are lazily activated in a chain sequentially.  Today it is single threaded which reduces the potential for out of order locks.  I think you will expose some dirty laundry in many bundles where they have no issues with single threaded but will deadlock when done in parallel.
Comment 2 Mark Hoffmann CLA 2018-10-26 10:17:55 EDT
The Java-Doc for the BundleActivator notes that "The Framework must not concurrently call a BundleActivator object. "

https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/BundleActivator.html

Beside this, in my opinion it is not the best strategy to solve problems just by making activation parallel. Instead, I would recommend investing the time, to avoid long running operations in BundleActivators.

Even if it seems not realistic, it is the right way. Working around it will not reduce the technical debt, but increase it. In addition to that, even if it would be allowed, to start bundles in parallel, it would also raise the grade of complexity instead of recuding it.
Comment 3 Lars Vogel CLA 2018-10-26 10:58:24 EDT
(In reply to Mark Hoffmann from comment #2)
> The Java-Doc for the BundleActivator notes that "The Framework must not
> concurrently call a BundleActivator object. "
> 
> https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/BundleActivator.html

That should be OK, as we would call different activators in parallel not accessing the same.

> Beside this, in my opinion it is not the best strategy to solve problems
> just by making activation parallel. Instead, I would recommend investing the
> time, to avoid long running operations in BundleActivators.


These days we have multiple cores so using them is a good pattern.

As the bug title says, we should investigate this, see if we break something and how much faster the startup gets. Afterwards, we can decide if we want to offer this as an option during startup or not.
Comment 4 Mark Hoffmann CLA 2018-10-26 12:51:26 EDT
(In reply to Lars Vogel from comment #3)
> 
> These days we have multiple cores so using them is a good pattern.

I didn't mean using parallelism in general is not a good pattern. 

Using long running operations in the BundleActivator is obviously not a good pattern:

https://help.eclipse.org/photon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fruntime_model_bundles.htm

This document recommends e.g. using operations in the start method, that can be performed quickly.


> As the bug title says, we should investigate this, see if we break something
> and how much faster the startup gets. Afterwards, we can decide if we want
> to offer this as an option during startup or not.

I think this is not the best way to solve a problem, that already has an obvious solution. It may be a quick solution to multi-thread the start of activators, but the costs are, like Thomas mentioned:
- increased probability for locks
- increased complexity in the launcher, to handle potential locks

It feels like a brute force way, to increase the startup time, without solving the real issues with long running activators.

Putting stuff into to services, that then can be injected into components, can be considered as an alternative, I think.
Comment 5 Mark Hoffmann CLA 2018-10-26 14:58:20 EDT
Created attachment 276392 [details]
Recommendation improvents for activator

I attached a quick rework of the JDT UI activator using OSGi Promises as well an additional component.

This was done without a testing, but should do the same. The launch time improvements were essential in my tests.

Maybe this helps for your investigation
Comment 6 Andrey Loskutov CLA 2018-10-26 14:59:31 EDT
(In reply to Mark Hoffmann from comment #5)
> Created attachment 276392 [details]
> Recommendation improvents for activator
> 
> I attached a quick rework of the JDT UI activator using OSGi Promises as
> well an additional component.
> 
> This was done without a testing, but should do the same. The launch time
> improvements were essential in my tests.
> 
> Maybe this helps for your investigation

Mark, can you please create Gerrit patch?
Comment 7 Eclipse Genie CLA 2018-11-02 09:12:19 EDT
New Gerrit change created: https://git.eclipse.org/r/131854
Comment 8 Eclipse Genie CLA 2018-11-02 15:51:00 EDT
New Gerrit change created: https://git.eclipse.org/r/131872
Comment 9 Thomas Watson CLA 2019-04-09 09:21:00 EDT
I have been taking a look at changes to the framework start-level implementation to start bundles with the same start-level in parallel.  So far I have not found much measurable startup improvements for Eclipse Platform startup.  But I have found significant improvements for scenarios that involve large number of bundles with many DS components.  In some scenarios I see a close to a 40% improvement with my 4 core i7 mac book using 8 threads to start the bundles.

I plan to add an option to enable this so we can experiment with using parallel bundle start.  By default the option will be disabled.
Comment 10 Lars Vogel CLA 2019-04-09 10:10:08 EDT
(In reply to Thomas Watson from comment #9)
> I plan to add an option to enable this so we can experiment with using
> parallel bundle start.  By default the option will be disabled.

Thanks Tom, great news.
Comment 11 Eclipse Genie CLA 2019-04-09 14:16:07 EDT
New Gerrit change created: https://git.eclipse.org/r/140322
Comment 13 Thomas Watson CLA 2019-04-12 10:50:51 EDT
I'm closing this as fixed as I have merged the initial work to allow parallel bundle activation.

I may do some follow up work to adjust the number of threads used by default when the value of "0" is used for the config option.  Right now a "0" value will cause the thread count to be equal to java.lang.Runtime.availableProcessors().  In some cases I have found that increasing that to 2 x java.lang.Runtime.availableProcessors() gives a bit more performance boost.  That could be important when running in a docker environment when you typically are not given all the processors.  I think it is common only to get 2.

Here is the commit message with the options that can be enabled to try it out:

By default the framework start-level implementation activates all
bundles that have the same start-level in sequential order using the
bundle ID (install order) to determine the order the bundles are started
from a single thread.

A new configuration option is added equinox.start.level.thread.count
that is set to 1 by default.  This will cause the framework to continue
with the behavior of activating all bundles with a single thread.

If equinox.start.level.thread.count is set to 0 then the framework will
use an executor with the number of threads == to
java.lang.Runtime.availableProcessors() to activate the bundles in
parallel.  This means that the order the bundles with the same
start-level are activated becomes random.  The
equinox.start.level.thread.count config setting can also be set to a
value > 1 to give an explicit value for the number of threads to use
(instead of using java.lang.Runtime.availableProcessors() to determine
the number)
Comment 14 Mickael Istria CLA 2019-04-12 12:44:36 EDT
Can you please add a note in the N&N?
Comment 15 Lars Vogel CLA 2019-04-16 03:34:44 EDT
Thanks, Thomas for the development.  I did run several starts of a runtime Eclipse but the deviation in startup time seems very high. I measure with the same setting between 6 and ~9 seconds.

Can you recommend a reasonable way to measure startup performance with this setting for the IDE?
Comment 16 Eclipse Genie CLA 2019-04-18 09:51:19 EDT
New Gerrit change created: https://git.eclipse.org/r/140824
Comment 17 Thomas Watson CLA 2019-04-18 10:01:04 EDT
(In reply to Lars Vogel from comment #15)
> Thanks, Thomas for the development.  I did run several starts of a runtime
> Eclipse but the deviation in startup time seems very high. I measure with
> the same setting between 6 and ~9 seconds.
> 
> Can you recommend a reasonable way to measure startup performance with this
> setting for the IDE?

I don't see the fluctuations like you do.  I usually just edit the config.ini to set:

equinox.start.level.thread.count=-1

Then I start with the native launcher using the "-debug -data testworkspace" options

This prints out 

Starting application: 910
Application started in : 6170ms

You should know that only that first number from "Starting application" can really be influenced by the parallel bundle activation from the start-level launch.  By this time all the bundles have been activated by the framework.  The rest of the activation that occurs in a typical Eclipse launch happens in response to a class load with lazy activation.

This is one reason I think you will find very little gain in parallel bundle activation at this level, because most of Eclipse bundles are lazy activated with a trigger class load.  That activation then happens on the thread that is loading the class.
Comment 18 Thomas Watson CLA 2019-04-18 10:03:26 EDT
Furthermore, I really only think this parallel bundle activation from the framework launch helps in cases where many bundles are installed that are eagerly activated.
Comment 20 Eclipse Genie CLA 2019-04-18 11:09:47 EDT
New Gerrit change created: https://git.eclipse.org/r/140831
Comment 22 Eclipse Genie CLA 2019-04-18 12:08:00 EDT
New Gerrit change created: https://git.eclipse.org/r/140837
Comment 24 Lars Vogel CLA 2019-04-26 05:52:14 EDT
Thomas, can you post your eclipse.ini file? I might doing something silly in my setup, as I cannot see any startup differences.
Comment 25 Thomas Watson CLA 2019-04-26 09:20:13 EDT
(In reply to Lars Vogel from comment #24)
> Thomas, can you post your eclipse.ini file? I might doing something silly in
> my setup, as I cannot see any startup differences.

See my comment 17.  Because of the use of lazy activation with class loading triggers, I see very little benefit of parallel activation for Eclipse startup.  It helps for other usages of OSGi where there are lots of eager start bundles with many service components.  This is the more traditional scenario for OSGi.

Again, I simply add the following to the end of my config.ini

equinox.start.level.thread.count=-1

It does not surprise me that you see no difference because that is what I see also.
Comment 26 Lars Vogel CLA 2019-05-20 04:16:46 EDT
Thomas, please add to N&N for 4.12
Comment 27 Eclipse Genie CLA 2019-05-22 09:41:01 EDT
New Gerrit change created: https://git.eclipse.org/r/142593
Comment 28 Thomas Watson CLA 2019-05-22 09:42:47 EDT
(In reply to Eclipse Genie from comment #27)
> New Gerrit change created: https://git.eclipse.org/r/142593

Lars, I have a gerrit review here to add it.  Not sure why I cannot submit the change from gerrit.
Comment 30 Dani Megert CLA 2019-05-23 03:50:24 EDT
(In reply to Thomas Watson from comment #28)
> (In reply to Eclipse Genie from comment #27)
> > New Gerrit change created: https://git.eclipse.org/r/142593
> 
> Not sure why I cannot submit the change from gerrit.
The verified +1 was missing. I've merged it.
Comment 31 Dani Megert CLA 2019-05-24 11:10:53 EDT
I see random full builds when switching to a new build. It looks like a timing issue. Could this be caused by this bug fix?
Comment 32 Thomas Watson CLA 2019-05-24 11:58:56 EDT
(In reply to Dani Megert from comment #31)
> I see random full builds when switching to a new build. It looks like a
> timing issue. Could this be caused by this bug fix?

I don't see how because this option is disabled by default.  How long have you seen this?
Comment 33 Dani Megert CLA 2019-05-24 12:38:06 EDT
(In reply to Thomas Watson from comment #32)
> (In reply to Dani Megert from comment #31)
> > I see random full builds when switching to a new build. It looks like a
> > timing issue. Could this be caused by this bug fix?
> 
> I don't see how because this option is disabled by default.  How long have
> you seen this?
Thanks Tom. I've figured out the issue. I imported an e4 test bundle that was causing this (triggering bug 547633).