Skip to content

fix: resolve parDemuxScan deadlock when worker throws with full buffer #8962

fix: resolve parDemuxScan deadlock when worker throws with full buffer

fix: resolve parDemuxScan deadlock when worker throws with full buffer #8962

Workflow file for this run

# packcheck-0.7.1
# You can use any of the options supported by packcheck as environment
# variables here. See https://github.com/composewell/packcheck for all
# options and their explanation.
name: TEST
#-----------------------------------------------------------------------------
# Events on which the build should be triggered
#-----------------------------------------------------------------------------
on:
workflow_dispatch:
pull_request:
push:
branches:
- master
#-----------------------------------------------------------------------------
# Build matrix
#-----------------------------------------------------------------------------
jobs:
build:
name: >-
${{ matrix.runner }}
${{ matrix.command }}
${{ matrix.ghc_version }}
${{ matrix.name }}
env:
# ------------------------------------------------------------------------
# What to build
# ------------------------------------------------------------------------
# DISABLE_TEST: "y"
# DISABLE_BENCH: "y"
# DISABLE_DOCS: "y"
# DISABLE_SDIST_BUILD: "y"
# DISABLE_SDIST_GIT_CHECK: "y"
# DISABLE_DIST_CHECKS: "y"
# ------------------------------------------------------------------------
# Selecting tool versions
# ------------------------------------------------------------------------
# For updating see: https://downloads.haskell.org/~ghcup/
#GHCUP_VERSION: 0.1.50.2
# ------------------------------------------------------------------------
# cabal options
# ------------------------------------------------------------------------
# CABAL_BUILD_OPTIONS="-j1"
# Enable the above option if you:
# 1. want logs in serial order to be able to correlate them better.
#
# 2. run into memory issues due to Build paralellism. We need to
# have sufficient per CPU memory, if not we can use a lower -j
# option; cabal default is ncpus.
#
# Currently (2026-03-12) from packcheck output we see:
# Linux: 15GB, 4 cpus
# macOS: 7GB, 3 cpus
# Windows: 16GB, 4 cpus
# ------------------------------------------------------------------------
# stack options (if using stack builds)
# ------------------------------------------------------------------------
# Note requiring a specific version of stack using STACKVER may fail due to
# github API limit while checking and upgrading/downgrading to the specific
# version.
#STACKVER: "1.6.5"
#STACK_UPGRADE: "y"
# ------------------------------------------------------------------------
# Common options
# ------------------------------------------------------------------------
# Subdir
SUBDIR: ${{ matrix.subdir }}
# If this option is enabled packcheck clears out the environment
# and only uses the options explicitly set on the command line,
# implicit environment won't affect the build. if you find this
# annoying comment this.
CHECK_ENV: "y"
# NOTE: by capturing the options in env variables here quotes
# are presrved, if we expand them directly into the script
# quotes are lost.
#
# WARNING! you cannot use comments in this
COMMON_OPTIONS: >-
LC_ALL=C.UTF-8
BUILD_PREFETCH=y
GHCUP_VERSION=latest
GHCVER=${{ matrix.ghc_version }}
DISABLE_SDIST_BUILD="y"
DISABLE_BENCH="y"
DISABLE_DOCS="y"
# WARNING! you cannot use comments in this
CABAL_OPTIONS: >-
CABAL_REINIT_CONFIG=y
CABAL_CHECK_RELAX=y
MATRIX_OPTIONS: ${{ matrix.pack_options }}
# ------------------------------------------------------------------------
# Location of packcheck.sh (the shell script invoked to perform CI tests ).
# ------------------------------------------------------------------------
# You can either commit the packcheck.sh script in your repo root or
# you can use it by specifying the PACKCHECK_REPO_URL option.
# If you have not committed packcheck.sh in your repo at PACKCHECK
# then it is automatically pulled from this URL.
PACKCHECK_GITHUB_URL: "https://raw.githubusercontent.com/composewell/packcheck"
PACKCHECK_GITHUB_COMMIT: "b3743510c7c26f83254ffd9ef91bcd71560cff05"
# Pull token from "secrets" setting of the github repo
#COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
#COVERAGE: ${{ matrix.coverage }}
# ubuntu seems to have better support than debian on CI systems
runs-on: ${{ matrix.runner }}
continue-on-error: ${{ matrix.ignore_error }}
strategy:
fail-fast: false
matrix:
# The order of jobs is important to optimize fail-fast, if
# fail-fast is set to true.
# This section is to order the important jobs first especially for
# "fail-fast" so that these are the ones started first.
name:
- werror
# IMPORTANT NOTE:
# If runner, command, ghc version are identical then the name of
# CI is used to distinguish the cache key.
# The reason we have an explicit "name" field in the following
# entries is to force an additional config instead of adding to
# an existing config while adding additional configs.
# Look at <https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix>
# for more info about adding matrix elements.
# Adding any element to the list will increase the number of matrix
# elements proportional to the cross product.
# Note: if cabal.project is not specified then benchmarks and
# tests won't run. But we need at least one test where we test
# without cabal.project because that is how hackage would build
# it.
include:
#- name: ci
# runner: ubuntu-latest
# command: cabal
# ghc_version: head
# # The URL may change, to find a working URL go to https://gitlab.haskell.org/ghc/ghc/-/jobs/
# # Find a debian10/11/12 job, click on a passed/failed status, at the
# # end of the output you will find the tar.xz name, put that tar
# # name after "raw/", and put the job name after "job=".
# # Also see https://github.com/mpickering/ghc-artefact-nix/blob/master/gitlab-artifact.nix
# #
# # May also use ghcup for installing ghc head version, use the
# # version "LatestNightly", and the following config:
# # ghcup config add-release-channel https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml
# # WARNING! cannot use # comments inside pack_options.
# pack_options: >-
# GHCUP_GHC_OPTIONS="-u https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-deb10-int_native-validate.tar.xz?job=x86_64-linux-deb10-int_native-validate"
# CABAL_PROJECT=cabal.project.ghc-head
# CABAL_BUILD_OPTIONS="--flag limit-build-mem"
# DISABLE_SDIST_BUILD="y"
# ignore_error: true
# Disable sdist build so that we can test all packages.
- name: fusion-bench-doc
runner: ubuntu-latest
command: cabal
ghc_version: 9.14.1
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
CABAL_BUILD_OPTIONS="--flag limit-build-mem --flag fusion-plugin"
DISABLE_DOCS="n"
DISABLE_BENCH="n"
ignore_error: false
- name: streamly-core-sdist
runner: ubuntu-latest
command: cabal
ghc_version: 9.14.1
subdir: core
ignore_error: false
- name: debug-no-opt
runner: macos-latest
command: cabal
ghc_version: 9.14.1
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
CABAL_BUILD_OPTIONS="--flag debug --flag -opt"
ignore_error: false
# Takes too long, so bench is disabled
- name: nightly-2026-03-10
runner: macos-latest
command: stack
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABALVER=3.14.2.0
STACK_UPGRADE="y"
RESOLVER=nightly-2026-03-10
STACK_YAML=stack.yaml
SDIST_OPTIONS="--ignore-check"
DISABLE_DIST_CHECKS="y"
ignore_error: false
# Note: use linux for warning build for convenient dev testing
- name: werror
runner: ubuntu-latest
command: cabal
ghc_version: 9.10.3
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project.Werror
CABAL_BUILD_OPTIONS="--flag limit-build-mem"
DISABLE_SDIST_BUILD="y"
DISABLE_BENCH="y"
ignore_error: false
- name: fusion-inspection
runner: ubuntu-latest
command: cabal
ghc_version: 9.10.3
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
CABAL_BUILD_OPTIONS="--flag fusion-plugin --flag inspection"
ignore_error: false
- name: ci
runner: ubuntu-latest
command: cabal
ghc_version: 9.8.4
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
ignore_error: false
- name: streamly-sdist
runner: ubuntu-latest
command: cabal
ghc_version: 9.6.3
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project.streamly
DISABLE_SDIST_BUILD="n"
ignore_error: true
- name: lstat-readdir
runner: ubuntu-latest
command: cabal
ghc_version: 9.4.7
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
CABAL_BUILD_OPTIONS="--flag force-lstat-readdir"
ignore_error: false
- name: custom-ghc
runner: ubuntu-latest
command: cabal
ghc_version: 9.2.8
ghc_salt: perf-counter-1
# WARNING! cannot use # comments inside pack_options.
# GHCUP_GHC_OPTIONS="-u https://s3.ap-south-1.amazonaws.com/downloads.portal.composewell.com/ghc/ghc-9.2.8-x86_64-unknown-linux.tar.xz"
pack_options: >-
GHCUP_GHC_OPTIONS="-u https://github.com/composewell/ghc/releases/download/ghc-9.2.8-perf-counters-1-rc1/ghc-9.2.8.20231130-x86_64-unknown-linux.tar.xz"
CABAL_PROJECT=cabal.project
ignore_error: false
- name: unoptimized
runner: ubuntu-latest
command: cabal
ghc_version: 8.10.7
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
CABAL_BUILD_OPTIONS="--flags \"-opt\""
ignore_error: false
- name: ci
runner: windows-latest
command: cabal
ghc_version: 9.12.4
# WARNING! cannot use # comments inside pack_options.
pack_options: >-
CABAL_PROJECT=cabal.project
ignore_error: false
#- name: ci
# runner: ubuntu-latest
# command: hlint
# # WARNING! cannot use # comments inside pack_options.
# pack_options: >-
# HLINT_VERSION=3.6.1
# HLINT_OPTIONS="lint"
# HLINT_TARGETS="src"
# ignore_error: false
# NOTE: need to expose other-modules in cabal to doctest those
#- name: docspec
# runner: ubuntu-latest
# command: cabal
# ghc_version: 9.12.4
# # WARNING! cannot use # comments inside pack_options.
# pack_options: >-
# DISABLE_SDIST_BUILD="y"
# DISABLE_TEST="y"
# DISABLE_BENCH="y"
# DISABLE_DOCS="y"
# ENABLE_DOCSPEC="y"
# DOCSPEC_URL=https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20250606/cabal-docspec-0.0.0.20250606-x86_64-linux.xz
# DOCSPEC_OPTIONS="--timeout 60 --check-properties --property-variables xs"
# CABAL_PROJECT="cabal.project.doctest"
# ignore_error: false
# - name: 8.10.7-coverage
# ghc_version: 8.10.7
# runner: ubuntu-latest
# coverage: "y"
# cabal_version: 3.6.2.0
# ignore_error: false
#-----------------------------------------------------------------------------
# Usually you do not need to change anything below, this is generic code for
# caching and running packcheck on Linux/Mac/Windows.
#-----------------------------------------------------------------------------
steps:
- name: Enable long paths on Windows
if: runner.os == 'Windows'
shell: powershell
continue-on-error: true
run: |
# Enable long paths. Sometimes failures occur due to path
# length limitation.
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1
# Cache saving is very slow on Windows, it could be due to tar,
# or the compression program or the file system. Changing the
# compression level of zstd does not help. We are also not able to pick
# another tar program by changing the path, tar is picked up by the
# cache action itself.
# This does not seem to make much difference.
# Disable Windows Defender to speed up IO/Tar operations
#Set-MpPreference -DisableRealtimeMonitoring $true
- uses: actions/checkout@v4
# This should happen before cache restore.
- name: Remove ~/.ghcup symlink (non-Windows)
if: runner.os != 'Windows'
run: |
rm -f ~/.ghcup
# See the "cabal path" output in the CI logs to tweak the cache
# locations.
# Shared by all tests, all platforms
- name: Restore hackage package index (non-Windows)
id: restore-hackage
uses: actions/cache/restore@v4
if: runner.os != 'Windows'
with:
path: |
~/.cache/cabal/packages
key: cabal-hackage-index-non-windows
# GHC is not test/options specific
- name: Restore ghcup and ghc (non-Windows)
id: restore-ghcup
uses: actions/cache/restore@v4
if: runner.os != 'Windows'
with:
path: |
~/.ghcup
key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}
# GHC is not test/options specific
#- name: Restore ghcup and ghc (Windows)
# id: restore-ghcup-win
# uses: actions/cache/restore@v4
# if: runner.os == 'Windows'
# with:
# path: |
# C:/ghcup
# key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}
# XXX If we want to invalidate the cache on resolver change we
# should use a separate cache for stack as it should be keyed on
# resolver as well. But that requires resolver as a matrix element
# and then copied to pack_options from there, needs some work. It
# should be fine as resolver minor version change can only increase
# the cache size.
# Deps are test/options specific
- name: Restore build dependencies (non-Windows)
id: restore-deps-nonwin
uses: actions/cache/restore@v4
if: runner.os != 'Windows'
with:
# cabal: ~/.local/bin, ~/.local/state/cabal
# ~/.cache/cabal/packages can be cached, but will increase the
# cache size. But can save the "cabal update" time.
path: |
~/.local/bin
~/.local/state/cabal
~/.stack
key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }}
# Deps are test/options specific
- name: Restore build dependencies, hackage index, local/bin (Windows)
id: restore-deps-win
uses: actions/cache/restore@v4
if: runner.os == 'Windows'
with:
path: |
C:/cabal
key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }}
- name: Download packcheck
# on windows-latest GitHub Actions defaults to PowerShell
shell: bash
run: |
download_one () {
if test ! -e "$1"
then
if test -z "$PACKCHECK_GITHUB_COMMIT"
then
die "Downloading [$1]: PACKCHECK_GITHUB_COMMIT env var is not specified."
fi
PACKCHECK_URL_PREFIX=${PACKCHECK_GITHUB_URL}/${PACKCHECK_GITHUB_COMMIT}
curl --fail -sLO ${PACKCHECK_URL_PREFIX}/$1 || exit 1
chmod +x "$1"
elif test ! -x "$1"
then
chmod +x $1
fi
}
if test -n "$SUBDIR"; then
cd "$SUBDIR"
fi
download_one packcheck.sh
# Store the function in a file so that it can be reused across multiple
# steps.
- name: Setup packcheck
shell: bash
run: |
if test -n "$SUBDIR"; then
rm -f cabal.project
cd "$SUBDIR"
fi
cat << 'EOF' > packcheck-setup.sh
setup_packcheck_args() {
ARGS="${{ matrix.command }} $COMMON_OPTIONS"
if test "${{ matrix.command }}" = "cabal"; then
ARGS="$ARGS $CABAL_OPTIONS"
fi
# Caution: do not use matrix.pack_options directly here
# quotes will get stripped.
ARGS="$ARGS $MATRIX_OPTIONS"
PATH_VAR=/bin:/usr/bin:/sbin:/usr/sbin
case "$(uname)" in
Linux)
export GHCUP_INSTALL_BASE_PREFIX=$HOME
# Access usr/local seems to be much slower on github
#PATH_VAR="$PATH_VAR:/usr/local/.ghcup/bin"
;;
CYGWIN*|MINGW*|MSYS*)
for var in APPDATA CABAL_DIR; do
val="${!var}"
[ -n "$val" ] && ARGS="$ARGS $var=\"$(cygpath -u "$val")\""
done
ARGS="$ARGS CABAL_BUILDDIR=\"/c/b\" WINVER=$WINVER"
ARGS="$ARGS NUMBER_OF_PROCESSORS=$NUMBER_OF_PROCESSORS"
ARGS="$ARGS PROCESSOR_IDENTIFIER=\"$PROCESSOR_IDENTIFIER\""
PATH_VAR="$PATH_VAR:/c/ghcup:/c/Program Files/7-Zip:/mingw64/bin"
;;
esac
ARGS="$ARGS PATH=\"$PATH_VAR\""
export ARGS
}
EOF
- name: Run packcheck (dependencies only)
id: deps-only
# Check the relevant step based on the runner OS
if: |
(runner.os != 'Windows' && steps.restore-deps-nonwin.outputs.cache-hit != 'true') ||
(runner.os == 'Windows' && steps.restore-deps-win.outputs.cache-hit != 'true')
shell: bash
run: |
if test -n "$SUBDIR"; then
cd "$SUBDIR"
fi
source packcheck-setup.sh
setup_packcheck_args
eval "./packcheck.sh $ARGS BUILD_DEPS_ONLY=y"
- name: Save hackage package index (non-Windows)
uses: actions/cache/save@v4
if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-hackage.outputs.cache-hit != 'true'
with:
path: ~/.cache/cabal/packages
key: cabal-hackage-index-non-windows
- name: Save ghcup and ghc (non-Windows)
uses: actions/cache/save@v4
if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-ghcup.outputs.cache-hit != 'true'
with:
path: ~/.ghcup
key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}
# On Windows, ghc restore step takes 2-3 minutes whereas installing
# GHC takes less than 2 minutes. On top of this saving the ghc cache
# takes 7 minutes. So this does not make sense.
#- name: Save ghcup and ghc (Windows)
# uses: actions/cache/save@v4
# if: always() && steps.deps-only.outcome == 'success' && runner.os == 'Windows' && steps.restore-ghcup-win.outputs.cache-hit != 'true'
# with:
# path: |
# C:/ghcup
# key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}
# Deps are test/options specific, hence, matrix.name in the key
- name: Save build dependencies (non-Windows)
uses: actions/cache/save@v4
if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-deps-nonwin.outputs.cache-hit != 'true'
with:
path: |
~/.local/bin
~/.local/state/cabal
~/.stack
key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }}
# hackage package index is part of C:/cabal
# Deps are test/options specific, hence, matrix.name in the key
# Add if needed ~/AppData/Roaming/local
- name: Save build dependencies (Windows)
uses: actions/cache/save@v4
if: always() && steps.deps-only.outcome == 'success' && runner.os == 'Windows' && steps.restore-deps-win.outputs.cache-hit != 'true'
with:
path: |
C:/cabal
key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }}
- name: Run packcheck (final build)
shell: bash
run: |
if test -n "$SUBDIR"; then
cd "$SUBDIR"
fi
source packcheck-setup.sh
setup_packcheck_args
eval "./packcheck.sh $ARGS BUILD_PACKAGE_ONLY=y"
# Enable for debugging, this itself takes 50 sec on Windows, in packcheck
# build which is tiny.
#- name: Check cache locations
# shell: bash
# run: |
# # We want to see if any cache paths are symlinks; e.g. on github
# # ~/.ghcup is a pre-existing symlink to /usr/local.
# if [ "$RUNNER_OS" == "Windows" ]; then
# # Convert Windows paths to Unix-style for Bash
# APPDATA_UNIX=$(cygpath "$APPDATA")
# list="$APPDATA_UNIX/local C:/ghcup C:/cabal"
# else
# list="$HOME/.local/bin $HOME/.local/state/cabal $HOME/.ghcup $HOME/.stack"
# fi
# for dir in $list; do
# # macOS does not have --no-dereference option
# if [ -L "$dir" ]; then
# echo "$dir is a symlink -> $(readlink $dir)"
# elif [ -d "$dir" ]; then
# du -sh "$dir" 2>/dev/null || echo "$dir permission denied"
# else
# echo "$dir missing or not a dir"
# fi
# done
# echo
# #ls -ld $list 2>/dev/null || true
# ls -al $list 2>/dev/null || true