async fn start_attack(
        mut self,
        socket: Option<Socket>,
    ) -> Result<SwanlingAttack, SwanlingError> {
        trace!("start_attack: socket({:?})", socket);

        // The SwanlingAttackRunState is used while spawning and running the
        // SwanlingUser threads that generate the load test.
        let mut swanling_attack_run_state = self
            .initialize_attack(socket)
            .await
            .expect("failed to initialize SwanlingAttackRunState");

        // The Swanling parent process SwanlingAttack loop runs until Swanling shuts down. Swanling enters
        // the loop in AttackPhase::Idle, and exits in AttackPhase::Shutdown.
        loop {
            match self.attack_phase {
                // In the Idle phase the Swanling configuration can be changed by a Controller,
                // and otherwise nothing happens but sleeping an checking for messages.
                AttackPhase::Idle => {
                    if self.configuration.no_autostart {
                        // Sleep then check for further instructions.
                        if swanling_attack_run_state.idle_status_displayed {
                            let sleep_duration = tokio::time::Duration::from_millis(250);
                            debug!("sleeping {:?}...", sleep_duration);
                            swanling_attack_run_state.drift_timer = util::sleep_minus_drift(
                                sleep_duration,
                                swanling_attack_run_state.drift_timer,
                            )
                            .await;
                        // Only display informational message about being idle one time.
                        } else {
                            info!("Swanling is currently idle.");
                            swanling_attack_run_state.idle_status_displayed = true;
                        }
                    } else {
                        // Prepare to start the load test, resetting timers and counters.
                        self.reset_run_state(&mut swanling_attack_run_state).await?;
                        self.set_attack_phase(
                            &mut swanling_attack_run_state,
                            AttackPhase::Starting,
                        );
                    }
                }
                // In the Start phase, Swanling launches SwanlingUser threads and starts a SwanlingAttack.
                AttackPhase::Starting => {
                    self.update_duration();
                    self.spawn_attack(&mut swanling_attack_run_state)
                        .await
                        .expect("failed to start SwanlingAttack");
                }
                // In the Running phase, Swanling maintains the configured SwanlingAttack.
                AttackPhase::Running => {
                    self.update_duration();
                    self.monitor_attack(&mut swanling_attack_run_state).await?;
                }
                // In the Stopping phase, Swanling stops all SwanlingUser threads and optionally reports
                // any collected metrics.
                AttackPhase::Stopping => {
                    // If displaying metrics, update internal state reflecting how long load test
                    // has been running.
                    self.update_duration();
                    // Tell all running SwanlingUsers to stop.
                    self.stop_running_users(&mut swanling_attack_run_state)
                        .await?;
                    // Stop any running SwanlingUser threads.
                    self.stop_attack().await?;
                    // Collect all metrics sent by SwanlingUser threads.
                    self.sync_metrics(&mut swanling_attack_run_state, true)
                        .await?;
                    // Write an html report, if enabled.
                    self.write_html_report(&mut swanling_attack_run_state)
                        .await?;
                    // Shutdown Swanling or go into an idle waiting state.
                    if swanling_attack_run_state.shutdown_after_stop {
                        self.set_attack_phase(
                            &mut swanling_attack_run_state,
                            AttackPhase::Shutdown,
                        );
                    } else {
                        // Print metrics, if enabled.
                        if !self.configuration.no_metrics {
                            println!("{}", self.metrics);
                        }
                        self.set_attack_phase(&mut swanling_attack_run_state, AttackPhase::Idle);
                    }
                }
                // By reaching the Shutdown phase, break out of the SwanlingAttack loop.
                AttackPhase::Shutdown => break,
            }
            // Regularly synchronize metrics.
            self.sync_metrics(&mut swanling_attack_run_state, false)
                .await?;

            // Check if a Controller has made a request.
            self.handle_controller_requests(&mut swanling_attack_run_state)
                .await?;

            // Gracefully exit loop if ctrl-c is caught.
            if self.attack_phase != AttackPhase::Shutdown
                && swanling_attack_run_state.canceled.load(Ordering::SeqCst)
            {
                // Shutdown after stopping as the load test was canceled.
                swanling_attack_run_state.shutdown_after_stop = true;

                // No metrics to display when sitting idle, so disable.
                if self.attack_phase == AttackPhase::Idle {
                    self.metrics.display_metrics = false;
                }

                // Cleanly stop the load test.
                self.set_attack_phase(&mut swanling_attack_run_state, AttackPhase::Stopping);
            }
        }

        Ok(self)
    }
// Called internally in local-mode and gaggle-mode.
Called internally in local-mode and gaggle-mode.
Called internally in local - mode and gaggle - mode .
async fn start_attack(
        mut self,
        socket: Option<Socket>,
    ) -> Result<SwanlingAttack, SwanlingError> {
        trace!("start_attack: socket({:?})", socket);
        // The SwanlingAttackRunState is used while spawning and running the
        // SwanlingUser threads that generate the load test.
        let mut swanling_attack_run_state = self
            .initialize_attack(socket)
            .await
            .expect("failed to initialize SwanlingAttackRunState");
        // The Swanling parent process SwanlingAttack loop runs until Swanling shuts down. Swanling enters
        // the loop in AttackPhase::Idle, and exits in AttackPhase::Shutdown.
        loop {
            match self.attack_phase {
                // In the Idle phase the Swanling configuration can be changed by a Controller,
                // and otherwise nothing happens but sleeping an checking for messages.
                AttackPhase::Idle => {
                    if self.configuration.no_autostart {
                        // Sleep then check for further instructions.
                        if swanling_attack_run_state.idle_status_displayed {
                            let sleep_duration = tokio::time::Duration::from_millis(250);
                            debug!("sleeping {:?}...", sleep_duration);
                            swanling_attack_run_state.drift_timer = util::sleep_minus_drift(
                                sleep_duration,
                                swanling_attack_run_state.drift_timer,
                            )
                            .await;
                        // Only display informational message about being idle one time.
                        } else {
                            info!("Swanling is currently idle.");
                            swanling_attack_run_state.idle_status_displayed = true;
                        }
                    } else {
                        // Prepare to start the load test, resetting timers and counters.
                        self.reset_run_state(&mut swanling_attack_run_state).await?;
                        self.set_attack_phase(
                            &mut swanling_attack_run_state,
                            AttackPhase::Starting,
                        );
                    }
                }
                // In the Start phase, Swanling launches SwanlingUser threads and starts a SwanlingAttack.
                AttackPhase::Starting => {
                    self.update_duration();
                    self.spawn_attack(&mut swanling_attack_run_state)
                        .await
                        .expect("failed to start SwanlingAttack");
                }
                // In the Running phase, Swanling maintains the configured SwanlingAttack.
                AttackPhase::Running => {
                    self.update_duration();
                    self.monitor_attack(&mut swanling_attack_run_state).await?;
                }
                // In the Stopping phase, Swanling stops all SwanlingUser threads and optionally reports
                // any collected metrics.
                AttackPhase::Stopping => {
                    // If displaying metrics, update internal state reflecting how long load test
                    // has been running.
                    self.update_duration();
                    // Tell all running SwanlingUsers to stop.
                    self.stop_running_users(&mut swanling_attack_run_state)
                        .await?;
                    // Stop any running SwanlingUser threads.
                    self.stop_attack().await?;
                    // Collect all metrics sent by SwanlingUser threads.
                    self.sync_metrics(&mut swanling_attack_run_state, true)
                        .await?;
                    // Write an html report, if enabled.
                    self.write_html_report(&mut swanling_attack_run_state)
                        .await?;
                    // Shutdown Swanling or go into an idle waiting state.
                    if swanling_attack_run_state.shutdown_after_stop {
                        self.set_attack_phase(
                            &mut swanling_attack_run_state,
                            AttackPhase::Shutdown,
                        );
                    } else {
                        // Print metrics, if enabled.
                        if !self.configuration.no_metrics {
                            println!("{}", self.metrics);
                        }
                        self.set_attack_phase(&mut swanling_attack_run_state, AttackPhase::Idle);
                    }
                }
                // By reaching the Shutdown phase, break out of the SwanlingAttack loop.
                AttackPhase::Shutdown => break,
            }
            // Regularly synchronize metrics.
            self.sync_metrics(&mut swanling_attack_run_state, false)
                .await?;
            // Check if a Controller has made a request.
            self.handle_controller_requests(&mut swanling_attack_run_state)
                .await?;
            // Gracefully exit loop if ctrl-c is caught.
            if self.attack_phase != AttackPhase::Shutdown
                && swanling_attack_run_state.canceled.load(Ordering::SeqCst)
            {
                // Shutdown after stopping as the load test was canceled.
                swanling_attack_run_state.shutdown_after_stop = true;
                // No metrics to display when sitting idle, so disable.
                if self.attack_phase == AttackPhase::Idle {
                    self.metrics.display_metrics = false;
                }
                // Cleanly stop the load test.
                self.set_attack_phase(&mut swanling_attack_run_state, AttackPhase::Stopping);
            }
        }
        Ok(self)
    }
async fn start_attack ( mut self , socket : Option < Socket > , ) -> Result < SwanlingAttack , SwanlingError > { trace ! ( " " socket ) ; // The SwanlingAttackRunState is used while spawning and running the // SwanlingUser threads that generate the load test. let mut swanling_attack_run_state = self . initialize_attack ( socket ) . await . expect ( " " ) ; // The Swanling parent process SwanlingAttack loop runs until Swanling shuts down. Swanling enters // the loop in AttackPhase::Idle, and exits in AttackPhase::Shutdown. loop { match self . attack_phase { // In the Idle phase the Swanling configuration can be changed by a Controller, // and otherwise nothing happens but sleeping an checking for messages. AttackPhase :: Idle => { if self . configuration . no_autostart { // Sleep then check for further instructions. if swanling_attack_run_state . idle_status_displayed { let sleep_duration = tokio :: time :: Duration :: from_millis ( 250 ) ; debug ! ( " " sleep_duration ) ; swanling_attack_run_state . drift_timer = util :: sleep_minus_drift ( sleep_duration , swanling_attack_run_state . drift_timer , ) . await ; // Only display informational message about being idle one time. } else { info ! ( " " ) ; swanling_attack_run_state . idle_status_displayed = true ; } } else { // Prepare to start the load test, resetting timers and counters. self . reset_run_state ( & mut swanling_attack_run_state ) . await ? ; self . set_attack_phase ( & mut swanling_attack_run_state , AttackPhase :: Starting , ) ; } } // In the Start phase, Swanling launches SwanlingUser threads and starts a SwanlingAttack. AttackPhase :: Starting => { self . update_duration ( ) ; self . spawn_attack ( & mut swanling_attack_run_state ) . await . expect ( " " ) ; } // In the Running phase, Swanling maintains the configured SwanlingAttack. AttackPhase :: Running => { self . update_duration ( ) ; self . monitor_attack ( & mut swanling_attack_run_state ) . await ? ; } // In the Stopping phase, Swanling stops all SwanlingUser threads and optionally reports // any collected metrics. AttackPhase :: Stopping => { // If displaying metrics, update internal state reflecting how long load test // has been running. self . update_duration ( ) ; // Tell all running SwanlingUsers to stop. self . stop_running_users ( & mut swanling_attack_run_state ) . await ? ; // Stop any running SwanlingUser threads. self . stop_attack ( ) . await ? ; // Collect all metrics sent by SwanlingUser threads. self . sync_metrics ( & mut swanling_attack_run_state , true ) . await ? ; // Write an html report, if enabled. self . write_html_report ( & mut swanling_attack_run_state ) . await ? ; // Shutdown Swanling or go into an idle waiting state. if swanling_attack_run_state . shutdown_after_stop { self . set_attack_phase ( & mut swanling_attack_run_state , AttackPhase :: Shutdown , ) ; } else { // Print metrics, if enabled. if ! self . configuration . no_metrics { println ! ( " " self metrics ) ; } self . set_attack_phase ( & mut swanling_attack_run_state , AttackPhase :: Idle ) ; } } // By reaching the Shutdown phase, break out of the SwanlingAttack loop. AttackPhase :: Shutdown => break , } // Regularly synchronize metrics. self . sync_metrics ( & mut swanling_attack_run_state , false ) . await ? ; // Check if a Controller has made a request. self . handle_controller_requests ( & mut swanling_attack_run_state ) . await ? ; // Gracefully exit loop if ctrl-c is caught. if self . attack_phase != AttackPhase :: Shutdown && swanling_attack_run_state . canceled . load ( Ordering :: SeqCst ) { // Shutdown after stopping as the load test was canceled. swanling_attack_run_state . shutdown_after_stop = true ; // No metrics to display when sitting idle, so disable. if self . attack_phase == AttackPhase :: Idle { self . metrics . display_metrics = false ; } // Cleanly stop the load test. self . set_attack_phase ( & mut swanling_attack_run_state , AttackPhase :: Stopping ) ; } } Ok ( self ) }
Called internally in local-mode and gaggle-mode.
Called internally in local - mode and gaggle - mode .
mut self
socket
Option<Socket>