multipool 0.2.8

A configurable thread pool with optional work-stealing support and task priority scheduling.
Documentation
name: Rust CI

on:
  push:
    branches:
      - "**" # Run for all branches on commit
  pull_request:
    branches:
      - "**" # Run for all pull requests

permissions:
  issues: write
  pull-requests: write

jobs:
  msrv:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2

      - name: Install Rust (MSRV)
        uses: actions-rs/toolchain@v1
        with:
          toolchain: 1.78.0
          override: true

      - name: Build and Test
        run: |

          cargo build --release
          cargo test

      - name: Run Benchmarks
        run: cargo bench --features bench

      # Parse benchmark results from target/criterion directories
      - name: Parse Benchmark Results
        run: |

          npm install glob
        shell: bash

      - name: Create Consolidated Benchmark Results
        id: create_results
        uses: actions/github-script@v6
        with:
          script: |

            const fs = require('fs');
            const path = require('path');
            const glob2 = require('glob');

            const files = glob2.sync('target/criterion/**/new/estimates.json', { ignore: '**/report/**' });

            const benchmarks = [];
            for (const file of files) {
              const estimates = JSON.parse(fs.readFileSync(file, 'utf8'));

              // Split the path into parts
              const normalizedFile = file.replace(/\\/g, '/');
              const parts = normalizedFile.split('/');
              const indexOfCriterion = parts.indexOf('criterion');
              const indexOfNew = parts.indexOf('new');
              
              // Extract the part(s) of the path between 'criterion' and 'new'
              // For example: target/criterion/<group>/<test>/new/estimates.json
              // becomes <group>/<test>
              const relevantParts = parts.slice(indexOfCriterion + 1, indexOfNew);
              const benchmarkName = relevantParts.join('/');

              // Extract the mean estimate in ns
              let mean_ns = estimates.mean ? estimates.mean.point_estimate : null;
              if (mean_ns !== null) {
                // Convert units if needed
                let value = mean_ns;
                let unit = 'ns';

                // If ≥ 1 second
                if (value >= 1e9) {
                  value = value / 1e9; // ns to s
                  unit = 's';
                } else if (value >= 1e6) {
                  // If ≥ 1 ms but < 1 s
                  value = value / 1e6; // ns to ms
                  unit = 'ms';
                }
                
                // Round to 3 decimal places
                value = parseFloat(value.toFixed(3));

                benchmarks.push({
                  name: benchmarkName,
                  value: value,
                  unit: unit
                });
              }
            }

            fs.mkdirSync('bench_results', { recursive: true });
            fs.writeFileSync('bench_results/results.json', JSON.stringify(benchmarks, null, 2));
            return { benchmarks };

      - name: Upload Benchmark Results
        uses: actions/upload-artifact@v3
        with:
          name: rust-msrv-bench--${{ matrix.os }}
          path: bench_results/results.json

      - name: Post Benchmark Results on Pull Requests
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |

            const fs = require('fs');
            const results = fs.readFileSync('bench_results/results.json', 'utf8');
            const benchmarks = JSON.parse(results);

            // Create a Markdown table
            const header = "| Benchmark Name | Value | Unit |\n|---|---|---|";
            const rows = benchmarks.map(b => `| ${b.name} | ${b.value} | ${b.unit} |`).join('\n');
            const table = `${header}\n${rows}`;

            const comment = `### Benchmark Results (MSRV)- ${{ matrix.os }}\n${table}`;
            github.rest.issues.createComment({
              issue_number: context.payload.pull_request.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

      - name: Display Benchmark Results in Logs
        if: github.event_name != 'pull_request'
        run: |

          echo "### Benchmark Results"
          cat bench_results/results.json

  latest:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2

      - name: Install Latest Stable Rust
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          override: true

      - name: Build and Test
        run: |

          cargo build --release
          cargo test

      - name: Run Benchmarks
        run: cargo bench --features bench

      - name: Parse Benchmark Results
        run: |

          npm install glob
        shell: bash

      - name: Create Consolidated Benchmark Results
        id: create_results
        uses: actions/github-script@v6
        with:
          script: |

            const fs = require('fs');
            const path = require('path');
            const glob2 = require('glob');

            const files = glob2.sync('target/criterion/**/new/estimates.json', { ignore: '**/report/**' });

            const benchmarks = [];
            for (const file of files) {
              const estimates = JSON.parse(fs.readFileSync(file, 'utf8'));

              // Split the path into parts
              const normalizedFile = file.replace(/\\/g, '/');
              const parts = normalizedFile.split('/');
              const indexOfCriterion = parts.indexOf('criterion');
              const indexOfNew = parts.indexOf('new');
              const relevantParts = parts.slice(indexOfCriterion + 1, indexOfNew);
              const benchmarkName = relevantParts.join('/');

              let mean_ns = estimates.mean ? estimates.mean.point_estimate : null;
              if (mean_ns !== null) {
                let value = mean_ns;
                let unit = 'ns';

                if (value >= 1e9) {
                  value = value / 1e9; // convert ns to s
                  unit = 's';
                } else if (value >= 1e6) {
                  value = value / 1e6; // convert ns to ms
                  unit = 'ms';
                }

                value = parseFloat(value.toFixed(3));

                benchmarks.push({
                  name: benchmarkName,
                  value: value,
                  unit: unit
                });
              }
            }

            fs.mkdirSync('bench_results', { recursive: true });
            fs.writeFileSync('bench_results/results.json', JSON.stringify(benchmarks, null, 2));
            return { benchmarks };

      - name: Upload Benchmark Results
        uses: actions/upload-artifact@v3
        with:
          name: rust-latest-bench--${{ matrix.os }}
          path: bench_results/results.json

      - name: Post Benchmark Results on Pull Requests
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |

            const fs = require('fs');
            const results = fs.readFileSync('bench_results/results.json', 'utf8');
            const benchmarks = JSON.parse(results);

            const header = "| Benchmark Name | Value | Unit |\n|---|---|---|";
            const rows = benchmarks.map(b => `| ${b.name} | ${b.value} | ${b.unit} |`).join('\n');
            const table = `${header}\n${rows}`;

            const comment = `### Benchmark Results (Latest) - ${{ matrix.os }}\n${table}`;
            github.rest.issues.createComment({
              issue_number: context.payload.pull_request.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

      - name: Display Benchmark Results in Logs
        if: github.event_name != 'pull_request'
        run: |

          echo "### Benchmark Results"
          cat bench_results/results.json