Repository: locustio/locust
File: locust/main.py (Python)

Code before:
                options.spawn_rate = 1
            if options.step_users is None:
                options.step_users = 1

            # start the test
            if options.step_time:
                runner.start_stepload(options.num_users, options.spawn_rate, options.step_users, options.step_time)
            if environment.shape_class:
                environment.runner.start_shape()
            else:
                runner.start(options.num_users, options.spawn_rate)

    if options.run_time:
        spawn_run_time_limit_greenlet()

    stats_printer_greenlet = None
    input_listener_greenlet = None
    if not options.only_summary and (options.print_stats or (options.headless and not options.worker)):
        # spawn stats printing greenlet
        stats_printer_greenlet = gevent.spawn(stats_printer(runner.stats))
        stats_printer_greenlet.link_exception(greenlet_exception_handler)

        input_listener_greenlet = gevent.spawn(
            input_listener(
                {
                    "w": lambda: runner.spawn_users(1, runner.spawn_rate),
                    "W": lambda: runner.spawn_users(10, runner.spawn_rate),
                    "s": lambda: runner.stop_users(1),
                    "S": lambda: runner.stop_users(10),
                }
            )
        )
        input_listener_greenlet.link_exception(greenlet_exception_handler)

    if options.csv_prefix:
        gevent.spawn(stats_csv_writer.stats_writer).link_exception(greenlet_exception_handler)

    gevent.spawn(stats_history, runner)

    def shutdown():
        """
        Shut down locust by firing quitting event, printing/writing stats and exiting
        """
        logger.info("Running teardowns...")

        if input_listener_greenlet is not None:
            input_listener_greenlet.kill(block=False)

        environment.events.quitting.fire(environment=environment, reverse=True)

        # determine the process exit code

Review comment (performance):
no need to use runner.spawn_rate, just do it immediately (set it to maybe 100). If people want to spawn slowly then let them wait between keypresses :) (when spawning only one user it will not matter anyway)

Code after:
                options.spawn_rate = 1
            if options.step_users is None:
                options.step_users = 1

            # start the test
            if options.step_time:
                runner.start_stepload(options.num_users, options.spawn_rate, options.step_users, options.step_time)
            if environment.shape_class:
                environment.runner.start_shape()
            else:
                runner.start(options.num_users, options.spawn_rate)

    if options.run_time:
        spawn_run_time_limit_greenlet()

    input_listener_greenlet = None
    if not options.worker:
        # spawn input listener greenlet
        input_listener_greenlet = gevent.spawn(
            input_listener(
                {
                    "w": lambda: runner.spawn_users(1, 100)
                    if runner.state != "spawning"
                    else logging.warning("Already spawning users, can't spawn more right now"),
                    "W": lambda: runner.spawn_users(10, 100)
                    if runner.state != "spawning"
                    else logging.warning("Already spawning users, can't spawn more right now"),
                    "s": lambda: runner.stop_users(1)
                    if runner.state != "spawning"
                    else logging.warning("Spawning users, can't stop right now"),
                    "S": lambda: runner.stop_users(10)
                    if runner.state != "spawning"
                    else logging.warning("Spawning users, can't stop right now"),
                }
            )
        )
        input_listener_greenlet.link_exception(greenlet_exception_handler)

    stats_printer_greenlet = None
    if not options.only_summary and (options.print_stats or (options.headless and not options.worker)):
        # spawn stats printing greenlet
        stats_printer_greenlet = gevent.spawn(stats_printer(runner.stats))
        stats_printer_greenlet.link_exception(greenlet_exception_handler)

    if options.csv_prefix:
        gevent.spawn(stats_csv_writer.stats_writer).link_exception(greenlet_exception_handler)

    gevent.spawn(stats_history, runner)

    def shutdown():
        """