diff --git a/.github/workflows/check-build.yml b/.github/workflows/check-build.yml index 0911fad..17d8af2 100644 --- a/.github/workflows/check-build.yml +++ b/.github/workflows/check-build.yml @@ -11,8 +11,15 @@ env: jobs: build: - runs-on: windows-latest + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + - os: windows-latest + target: x86_64-pc-windows-msvc + runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v2 @@ -20,12 +27,13 @@ jobs: uses: actions-rs/toolchain@v1 with: toolchain: stable - target: x86_64-pc-windows-msvc + target: ${{ matrix.target }} override: true + - name: Build with Cargo uses: actions-rs/cargo@v1 with: command: build - args: --release --target=x86_64-pc-windows-msvc + args: --release --target ${{ matrix.target }} - name: Run tests run: cargo test --verbose diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index ab80be3..d0a49bc 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -9,8 +9,17 @@ env: jobs: build: - runs-on: windows-latest + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + exec_name: rw3d_cli + - os: windows-latest + target: x86_64-pc-windows-msvc + exec_name: rw3d_cli.exe + runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v2 @@ -18,21 +27,41 @@ jobs: uses: actions-rs/toolchain@v1 with: toolchain: stable - target: x86_64-pc-windows-msvc + target: ${{ matrix.target }} override: true - name: Build with Cargo uses: actions-rs/cargo@v1 with: command: build - args: --package rw3d_cli --release --target=x86_64-pc-windows-msvc + args: --package rw3d_cli --release --target ${{ matrix.target }} + - name: Zip the executable uses: papeloto/action-zip@v1 with: - files: "target/x86_64-pc-windows-msvc/release/rw3d_cli.exe" - dest: "rw3d_cli_${{ github.ref_name }}.zip" - - name: Create draft release + files: "target/${{ matrix.target }}/release/${{ matrix.exec_name }}" + dest: "rw3d_cli-${{ github.ref_name }}-${{ matrix.target }}.zip" + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.target }} + path: "*.zip" + if-no-files-found: error + + publish: + runs-on: ubuntu-latest + needs: build + if: success() + + steps: + - name: Download artifacts + uses: actions/download-artifact@v2 + + - name: Prepare artifact list for release action + run: echo "ARTIFACTS=$(echo $(find . -iname "*.zip") | sed "s/ /,/g")" >> $GITHUB_ENV + - name: Create draft release on GitHub uses: ncipollo/release-action@v1 with: - artifacts: "rw3d_cli_${{ github.ref_name }}.zip" + artifacts: "${{ env.ARTIFACTS }}" draft: true + allowUpdates: true generateReleaseNotes: true diff --git a/crates/mock-server/src/lib.rs b/crates/mock-server/src/lib.rs index 8bbb3c1..55f3b72 100644 --- a/crates/mock-server/src/lib.rs +++ b/crates/mock-server/src/lib.rs @@ -13,7 +13,7 @@ type ServiceMap = HashMap>; impl MockWitcherServer { const LISTEN_INTERVAL_MILLIS: u64 = 500; - const PEEK_INTERVAL_MILLIS: u64 = 100; + const READ_TIMEOUT_MILLIS: u64 = 100; pub fn new() -> anyhow::Result> { let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, WitcherConnection::GAME_PORT))?; @@ -64,9 +64,13 @@ impl MockWitcherServer { Ok((socket, addr)) => { println!("Client connected on address {}", addr); + socket.set_nonblocking(false).unwrap(); + socket.set_read_timeout(Some(std::time::Duration::from_millis(Self::READ_TIMEOUT_MILLIS))).unwrap(); let self_clone = self.clone(); - std::thread::spawn(move || -> anyhow::Result<()> { - self_clone.serve_for(socket) + std::thread::spawn(move || { + if let Err(err) = self_clone.serve_for(socket) { + eprintln!("Server abruptly lost connection to the client: {}", err); + } }); } Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { @@ -89,12 +93,11 @@ impl MockWitcherServer { service.accept_packet(packet, &mut client_socket); } } - Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { - std::thread::sleep(std::time::Duration::from_millis(Self::PEEK_INTERVAL_MILLIS)); - }, Err(err) => { - eprintln!("{}", err); - break Err(err.into()); + if !matches!(err.kind(), std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut) { + + break Err(err.into()); + } } } } diff --git a/crates/net-client/tests/integration.rs b/crates/net-client/tests/integration.rs index 9216acb..956d465 100644 --- a/crates/net-client/tests/integration.rs +++ b/crates/net-client/tests/integration.rs @@ -16,6 +16,9 @@ fn integration_test() -> anyhow::Result<()> { Ok(()) }); + // wait for the server to set up + std::thread::sleep(std::time::Duration::from_millis(100)); + let conn = WitcherConnection::connect_timeout(Ipv4Addr::LOCALHOST.into(), Duration::from_secs(1))?; let client = WitcherClient::new(conn); client.start()?; diff --git a/crates/net/src/connection.rs b/crates/net/src/connection.rs index 3b75758..6243895 100644 --- a/crates/net/src/connection.rs +++ b/crates/net/src/connection.rs @@ -76,7 +76,7 @@ impl WitcherConnection { Ok(peeked) => { Ok(peeked >= peek_buffer.len()) } - Err(err) if matches!(err.kind(), std::io::ErrorKind::TimedOut) => { + Err(err) if matches!(err.kind(), std::io::ErrorKind::TimedOut | std::io::ErrorKind::WouldBlock) => { Ok(false) }, Err(err) => {