Commit Graph

62 Commits

Author SHA1 Message Date
Si Beaumont edad6d8a9b Clarify state and relationship of NIOFileSystem and _NIOFileSystem in API docs (#3504)
### Motivation:

`NIOFileSystem` currently exposes the same API as `_NIOFileSystem`,
which is not API stable. `NIOFileSystem`
was created in error, and its lack of underscore incorrectly implies API
stability. Users who are currently importing `NIOFileSystem` should
ideally move to `_NIOFileSystem`. However this isn't made clear in the
docs:

1. The README talks about the non-underscored `NIOFileSystem`.
2. There are no hosted API docs `NIOFileSystem`.
3. The hosted API docs for `NIO` point to the docs for `NIOFileSystem`
-- results in 404.

### Modifications:

- Update the README to refer to `_NIOFileSystem`.
- Update the hosted API docs for `NIO` to point to docs for
`_NIOFileSystem`.
- Add hosted API docs for `NIOFileSystem` with a statement explaining
the situation and pointing people to the docs
  for `_NIOFileSystem`.

### Result:

Clearer documentation on the state and relationship of the
`NIOFileSystem` and `_NIOFileSystem` modules.
2026-02-06 18:56:42 +00:00
George Barnett a18bddb0ac Add back NIOFileSystem (#3380)
Motivation:

We accidentally removed the 'NIOFileSystem' module from the
'_NIOFileSystem' product in the last release.

Modifications:

- Rename 'NIOFileSystem' and 'NIOFileSystemFoundationCompat' to 'NIOFS'
  and 'NIOFSFoundationCompat'
- Add back 'NIOFileSystem' which re-exports '_NIOFileSystem' (there was
  no publicly available 'NIOFileSystemFoundationCompat' module to
  remove, only '_NIOFileSystemFoundationCompat').

Result:

Fewer breaks
2025-09-23 17:29:01 +01:00
Cory Benfield f2ebedb36a The formatter changed its mind (#3379) 2025-09-23 14:58:24 +01:00
George Barnett 7290551b7f Add a NIOFilePath based NIOFileSystem (#3363)
Motivation:

We changed the file path type in `_NIOFileSystem` to use `NIOFilePath`
instead of `FilePath`. Originally we planned to use API shims to avoid
breaking API, however in some cases this was inevitable (i.e. where a
file path is returned to the caller).

To roll over to the new API we will instead introduce the
`NIOFileSystem` module using `NIOFilePath` and have `_NIOFileSystem` use
`FilePath`. Users can then opt-in to the new stable API rather than
having it forced upon them.

The first wave of these changes turns `_NIOFileSystem` into
`NIOFileSystem` and uses `NIOFilePath` for its APIs.

Modifications:

- Remove disfavoured overloads (i.e. `FilePath` APIs)
- Update the `DirectoryEntry` API to use `NIOFilePath`.
- Update tests to use `NIOFilePath` since many were relying on the newly
removed shims
- Remove the underscore from the module names and products
- Remove deprecated methods

A follow up change will re-instate the `_NIOFileSystem` (and compat)
module and products using `FilePath`.

Result:

`NIOFileSystem` has a stable API.
2025-09-01 08:11:14 +01:00
aryan-25 8997a24524 Update FilePath references to NIOFilePath (#3333)
Motivation:

Currently, file paths are represented by the `SystemPackage.FilePath`
type in `NIOFileSystem`. Following from #3322, we want to use
`NIOFilePath` instead.

Modifications:

This change provides `NIOFilePath` accepting/returning variants to all
existing public methods that accept/return `SystemPackage.FilePath`.

The bulk of the changes are in `FileSystemProtocol` and
`FileHandleProtocol`, and their conforming types. The protocols have
been modified to require `NIOFilePath` accepting/returning methods.
Default implementations are provided for `SystemPackage.FilePath`
accepting/returning methods---these call through to the `NIOFilePath`
variants.

Result:

`NIOFilePath` path representations can now be used with the methods for
interacting with the file system.

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2025-08-11 17:29:02 +01:00
aryan-25 96fbe40aae Add a new file path type, NIOFilePath, backed by SystemPackage's FilePath type (#3322)
Motivation:

Two separate types for representing file paths currently exist:
[`SystemPackage`'s
`FilePath`](https://swiftpackageindex.com/apple/swift-system/1.6.0/documentation/systempackage/filepath)
type and [`System`'s
`FilePath`](https://developer.apple.com/documentation/system/filepath)
type.

`NIOFileSystem` currently uses `SystemPackage`'s `FilePath`. However,
the lack of an API for converting between the two representations means
that users whose application also uses `System.FilePath` may find
interacting with `NIOFileSystem` difficult.

Modifications:

- Added `NIOFilePath`, and its subcomponents `NIOFilePath.Root`,
`NIOFilePath.Component`, and `NIOFilePath.ComponentView`.
- These types mirror the API of `SystemPackage`'s `FilePath` and are
internally backed by it.
- `NIOFilePath` can be initialized from either an instance of
`SystemPackage.FilePath` or `System.FilePath`.

Result:

Reduces the friction of interacting with `NIOFileSystem` by providing a
bridge between `SystemPackage.FilePath` and `System.FilePath`.

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2025-07-30 15:13:50 +01:00
Rafael Cepeda 02be63c7f4 Fixes all warnings when -require-explicit-sendable flag is enabled (#3320)
Fixes all warnings when `-require-explicit-sendable` flag is enabled and
enables the flag on macOS CI.

### Motivation:

We want to ensure our public API is either explicitly marked as
`Sendable` or not.

### Modifications:

Marked appropriate public types as `Sendable`, or explicitly defined
their conformance to the `Sendable` protocol as unavailable.

### Result:

We can now enable `-require-explicit-sendable` compiler flag in our
codebase.
2025-07-30 11:50:28 +01:00
Ali Ali fe923bbbe6 Make file handle sendable (#3300)
Solve Issue-3295

### Motivation:

Solve https://github.com/apple/swift-nio/issues/3295

### Modifications:

Make a few objects send able. 

### Result:

WriteFileHandle will be sendable

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2025-07-15 12:43:22 +00:00
Johannes Weiss 0b65385fad improve inEventLoop checks (#3302)
### Motivation:

`inEventLoop` is very much in the performance path of SwiftNIO,
especially these days with Concurrency, `NIOLoopBound` and friends.
Previously, we relied on `pthread_equal(pthread_self(), myPthread)`,
however, this could cause a number of issues.

1. Holding onto a `pthread_t` after `.join` is actually illegal (fixed
in #3297)
2. Potential ABA issues when `pthread_t` pointer are re-used for new
pthreads
3. Fix would require a lock around `myPthread` which makes things (2x
slower, even without contention)

### Modifications:

- New type `SelectableEventLoopUniqueID` which can be packed into a
`UInt`
- Attach them into a C thread local

### Result:

- Even faster than the old, incorrect version
- old: `measuring: el_in_eventloop_100M: 0.257395375, 0.241049208,
0.243188792, 0.259125916, 0.24843225, 0.229690125, 0.244281541,
0.225078834, 0.236395, 0.233305167`
- new: `measuring: el_in_eventloop_100M: 0.175561125, 0.187225625,
0.199269375, 0.19740975, 0.1922695, 0.179850958, 0.177612458,
0.17665125, 0.17897475, 0.18038775`
- More correct
- Groundwork to make #3297 not make things slower
2025-07-14 17:15:10 +01:00
Cory Benfield ad6b5f1727 Work around Android nullability errors (#3279)
Motivation:

Android messed up their nullability annotations in fts_open. The
original change in
https://android.googlesource.com/platform/bionic/+/dec8efd72a6ad8b807a15a614ae1519487cfa456
asserted that fts_open's path argument took a non-null pointer to an
array of non-null pointers to strings. That's challenging, because the
_end_ of that array is indicated by a null pointer.

Regardless, this was eventually fixed in

https://android.googlesource.com/platform/bionic/+/da81ec4d1cbd0279014feb60535bf38defcd9346.
Unfortunately, that was more than a year after the offending change, so
we need to work around it.

Modifications:

Add a shim for Android that omits the nullability annotations. Use that
shim on Android.

Result:

Android works again.
Resolves #3273.
2025-07-01 08:11:16 +01:00
Cory Benfield c9e2ac115f Adjust for SendableMetatype (#3266)
Motivation

With the introduction of isolated conformances, it has become necessary
to start managing the use of metatypes for some of our protocols. In
general, we don't want to force the relevant protocols to only be
conformed in non-isolated forms. Instead, we just want to make the
specific APIs non-usable.

Modifications

- Add shims for SendableMetatype that only use it when it is available.
- Require SendableMetatype where needed, gated by @preconcurrency.

Result

We continue to be safe.
2025-06-13 09:12:25 +01:00
Rick Newton-Rogers 14dcafc6ec Update Array+FileSystem.swift to add visionOS (#3220)
Fix visionOS builds and tests

### Motivation:

visionOS builds and tests were failing because of missing cases in
availability guards.

### Modifications:

Spell guards in terms of Darwin where appropriate, add visionOS

### Result:

Example run of this working in CI
https://github.com/apple/swift-nio/actions/runs/14876166161/job/41773757638?pr=3220
2025-05-07 13:22:23 +00:00
Johannes Weiss 40ee44c6b9 always @preconcurrency import Glibc/Musl/Android/Bionic/WASILibc (#3153)
### Motivation:

The non-`Darwin` libcs don't have the correct concurrency annotations.
But due to these Swift bugs, it's important that the _first_ importer
uses `@preconcurrency`:

- https://github.com/swiftlang/swift/issues/79414
- https://github.com/swiftlang/swift/issues/77866

### Modifications:

Much like the Foundation (& corelibs) PRs such as
https://github.com/swiftlang/swift-foundation/pull/1175 , use
`@preconcurrency import` for the non-`Darwin` libcs.

### Result:

Fewer bad warnings/errors in user code.
2025-03-21 15:35:05 +00:00
Cory Benfield 08b3b4f95e Make _NIOFileSystem strict concurrency compatible (#3098)
Motivation:

We're continuing out Strict Concurrency journey, making sure users of
NIO can write data-race-free code.

Modifications:

- Added some missing Sendable annotations in NIOAsyncSequenceProducer
- Made BufferedStream unconditionally Sendable, and required its Element
type to also be Sendable.

    The prior constraint wasn't actually correct. We always
    behaved as though the element types were Sendable, by passing
    them into continuations. This cleans things up.
- Made AnyAsyncSequence Sendable, which it needs to be.
- Made BufferedOrAnyStream Sendable, which it needs to be.
- Made DirectoryEntries explicitly Sendable, which it was.
- Made DirectoryEntries.Batched explicitly Sendable.

Result:

Better concurrency-safety
2025-02-03 17:56:57 +00:00
Natik Gadzhi 1e900b4736 NIOFileSystem: Try ${TMPDIR} first for temporary directory (#3067)
### Motivation:

This PR aligns what temp directory NIOFileSystem will return first:
- First try `${TMPDIR}` as it's an expressed user preference
- On Darwin, try `_CS_DARWIN_USER_TMP_DIR` next. If it's set, return
that.
- Finally, fall back on `/tmp` on Darwin and Linux, and
`/data/local/tmp` on Android.

Closes #2861.

### Modifications:

- Reworks `NIOFileSystem.temporaryDirectory`.

### Result:

- NIOFileSystem will now try `${TMPDIR}` first for the temporary
directory.

### Caveats:

- We might want to align how Swift-NIO and FoundationEssentials resolve
temp directory, and [FoundationEssentials have a different
approach](https://github.com/swiftlang/swift-foundation/blob/9d57f36de757b3d5e3a2f7ffcf27aaec3033509f/Sources/FoundationEssentials/String/String%2BPath.swift#L484-L533).
But, I agree with [this
comment](https://github.com/apple/swift-nio/issues/2861#issuecomment-2327010713),
it feels like TMPDIR is an expected default.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
Co-authored-by: George Barnett <gbarnett@apple.com>
2025-01-27 08:45:46 +00:00
Natik Gadzhi 30e1f2e3f4 feat: Add String(contentsOf: FilePath ...) (#3048)
### Motivation:

Makes it possible to read contents of an NIOFileSystem.FilePath into a
String directly. Closes #3010.

### Modifications:

- Added a new `String+FileSystem.swift` into `NIOFileSystem` target.
- Added basic tests to the existing `ConvenienceTests.swift`.
- Added a test to cover `Array+FileSystem` initializer as well.

### Result:

- String initializer for `FilePath` is now available
- Array initializer for `FilePath` now has a test

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-01-16 12:25:15 +00:00
finagolfin 47785adb51 Remove now unneeded fts_open bitcast for Android (#3025)
I added this changed function call for Android in #2660 earlier this
year, because of [an incorrect Bionic function signature as explained
recently](https://github.com/apple/swift-nio/pull/3009#discussion_r1864807270),
but now that it has been worked around through a new API note as
mentioned there, this change is no longer needed.

I simply did not notice this earlier because it still compiles and
merely gives a warning, which removing this call now silences.
2024-12-15 11:37:57 +00:00
Michael Gecht 29c65edb97 Add parallel removal of items (#3008)
Introduce parallel removal of items, instead of only doing a sequential
removal (and discovery) one-by-one

### Motivation:

#2933 mentioned this function call appears to be slow. If we attempt to
delete a directory with lots of subdirectories, we end up discovering
each subdirectory one by one on a single thread.

### Modifications:

This PR refactors the logic to remove items. Instead of sequentially
discovering and deleting items one by one, we traverse all directories
up to a maximum concurrency, and issue file deletions in parallel within
each directory.

### Result:

The new concurrent implementation was measured to be ~1.4x faster than
`FileManager`, ~1.5x faster than `rm -rf` and ~3x faster than the
current sequential implementation on `main`. This new concurrent
implementation does use the most CPU out of all the other approaches.

Results are broken down into two sections. We delete a copy of the
`swift-nio` repository, where the `.build/` folder has grown to a large
size, providing lots of additional files and subdirectories.

We produce a single CLI using `--configration=release` that can switch
between using the `.sequential` mode (what is currently available on the
`main` branch), `.parallel` (the new concurrent implementation in this
PR) and `filemanager` (uses `Foundation.FileManager` as a comparison).

Resolves https://github.com/apple/swift-nio/issues/2933

#### Normal size

**Description:** The `swift-nio` library as found when building the CLI
used for benchmarking.
**Benchmark run with:** 3579 directories, 11657 files

```
$ hyperfine --runs 10 --warmup 2 --prepare "rm -rf /tmp/swift-nio && cp -r $(pwd) /tmp/swift-nio" ".build/release/NIOTestCLI --sequential /tmp/swift-nio" ".build/release/NIOTestCLI --parallel /tmp/swift-nio" ".build/release/NIOTestCLI --filemanager /tmp/swift-nio" "rm -rf /tmp/swift-nio"
Benchmark 1: .build/release/NIOTestCLI --sequential /tmp/swift-nio
  Time (mean ± σ):      2.712 s ±  0.053 s    [User: 0.526 s, System: 8.632 s]
  Range (min … max):    2.625 s …  2.781 s    10 runs

Benchmark 2: .build/release/NIOTestCLI --parallel /tmp/swift-nio
  Time (mean ± σ):     896.7 ms ±  25.6 ms    [User: 302.9 ms, System: 5313.5 ms]
  Range (min … max):   853.2 ms … 942.1 ms    10 runs

Benchmark 3: .build/release/NIOTestCLI --filemanager /tmp/swift-nio
  Time (mean ± σ):      1.337 s ±  0.076 s    [User: 0.022 s, System: 1.253 s]
  Range (min … max):    1.252 s …  1.508 s    10 runs

Benchmark 4: rm -rf /tmp/swift-nio
  Time (mean ± σ):      1.483 s ±  0.037 s    [User: 0.015 s, System: 1.416 s]
  Range (min … max):    1.413 s …  1.541 s    10 runs

Summary
  .build/release/NIOTestCLI --parallel /tmp/swift-nio ran
    1.49 ± 0.10 times faster than .build/release/NIOTestCLI --filemanager /tmp/swift-nio
    1.65 ± 0.06 times faster than rm -rf /tmp/swift-nio
    3.02 ± 0.10 times faster than .build/release/NIOTestCLI --sequential /tmp/swift-nio
```

#### Large size

**Description:** The `swift-nio` library as found after re-running the
`.github` workflow many times locally. I'm unable to reproduce this
directory size, but have benchmarked against it.
**Benchmark run with:** 15260 directories, 46842 files

```
$ hyperfine --runs 10 --warmup 2 --prepare "rm -rf /tmp/swift-nio && cp -r $(pwd) /tmp/swift-nio" ".build/release/NIOTestCLI --sequential /tmp/swift-nio" ".build/release/NIOTestCLI --parallel /tmp/swift-nio" ".build/release/NIOTestCLI --filemanager /tmp/swift-nio" "rm -rf /tmp/swift-nio"
Benchmark 1: .build/release/NIOTestCLI --sequential /tmp/swift-nio
  Time (mean ± σ):     12.082 s ±  0.354 s    [User: 2.180 s, System: 41.547 s]
  Range (min … max):   11.717 s … 12.923 s    10 runs

Benchmark 2: .build/release/NIOTestCLI --parallel /tmp/swift-nio
  Time (mean ± σ):      4.770 s ±  0.102 s    [User: 1.357 s, System: 25.785 s]
  Range (min … max):    4.570 s …  4.883 s    10 runs

Benchmark 3: .build/release/NIOTestCLI --filemanager /tmp/swift-nio
  Time (mean ± σ):      6.503 s ±  0.115 s    [User: 0.081 s, System: 5.427 s]
  Range (min … max):    6.262 s …  6.687 s    10 runs

Benchmark 4: rm -rf /tmp/swift-nio
  Time (mean ± σ):      7.056 s ±  0.246 s    [User: 0.064 s, System: 6.119 s]
  Range (min … max):    6.435 s …  7.233 s    10 runs

Summary
  .build/release/NIOTestCLI --parallel /tmp/swift-nio ran
    1.36 ± 0.04 times faster than .build/release/NIOTestCLI --filemanager /tmp/swift-nio
    1.48 ± 0.06 times faster than rm -rf /tmp/swift-nio
    2.53 ± 0.09 times faster than .build/release/NIOTestCLI --sequential /tmp/swift-nio
```

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2024-12-10 17:43:29 +00:00
finagolfin 33b8a4801f Use the new Android overlay in the tests and update some Bionic declarations (#3009)
### Motivation:

Get this repo building again for Android with NDK 27

### Modifications:

- Update some networking declarations for newly added nullability
annotations
- Import the new Android overlay instead in some tests
- Add two force-unwraps on all platforms, that are needed for Android

### Result:

This repo and its tests build for Android again

I've been [using these patches on my Android
CI](https://github.com/finagolfin/swift-android-sdk/blob/main/swift-nio-ndk27.patch)
and natively on Android for a couple months now. I didn't bother keeping
this patch building for Android with Swift 5 anymore, as my Android CI
no longer tests Swift 5.

I built this pull and ran the tests on linux x86_64 to make sure there
was no regression.
2024-12-01 17:57:08 +00:00
Michael Gecht 4d2fb577b9 Update documentation comments (#2998)
Updates to documentation comments in `NIOFileSystem`.

### Motivation:

I've been reviewing some parts of `NIOFileSystem` and came across a
variety of formatting of documentation comments.

### Modifications:

I've adopted a stricter 100-character limit (arbitrary, really; it could
be longer or shorter and is totally not consistent with the rest of the
repository). Also updated a bunch of grammar in comments. Fixed a few
typos along the way.

### Result:

- Updated comments have a better flow while reading, and aren't as
abrupt as before.
- Fewer typos in comments

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2024-11-26 14:48:29 +00:00
Johannes Weiss 6ba8f4f04a fix almost all Sendable warnings (#2994)
### Motivation:

Opening the `swift-nio` repository made me warning blind because there
were always so many trivially fixable warnings about things that were
correct but cannot be understood by the compiler.

### Modifications:

Fix all the sendable warnings that popped up, except for one test where
`NIOLockedValueBox<Thread?>` isn't sendable because `Foundation.Thread`
seemingly isn't `Sendable` which is odd. Guessing that'll be fixed on
their end.

### Result:

- Fewer warnings
- Less warning-blindness
- More checks
2024-11-25 17:56:44 +00:00
Rick Newton-Rogers adfd61adc5 Use Swift 6.0 docs pipeline (#2966)
### Motivation:

Documentation checking catches more issues in Swift 6.0.

### Modifications:

Adopt the Swift 6.0 image and fix the errors.

### Result:

More accurate docs.
2024-11-07 13:03:47 +00:00
Ali Ali 9140817010 Issue-2900 - Add VisionOS support (#2947)
Add Vision support

### Motivation:
https://github.com/apple/swift-nio/issues/2900 - close this

### Modifications:
- Bump SystemPackage to 1.4.0 and remove @preconcurrency 
- remove `#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) ||
os(Linux) || os(Android)` to allow for visionOS support
- Remove conditional import for swift system

### Result:

Vision OS support
2024-10-24 10:26:32 +00:00
Clinton Nkwocha cc1c57c291 Provide APIs to read file into more data types (#2923)
Motivation:

As requested in issues
[#2875](https://github.com/apple/swift-nio/issues/2875) and
[#2876](https://github.com/apple/swift-nio/issues/2876), it would be
convenient to be able to read the contents of a file into more data
types such as `Array`, `ArraySlice` & Foundation's `Data`.

Modifications:

- Extend `Array`, `ArraySlice` & `Data` to be initialisable with the
contents of a file.

Result:

The contents of a file can be read into more data types.

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2024-10-21 08:41:10 +00:00
Rick Newton-Rogers fcdb6c3bf3 Adopt NIOThrowingAsyncSequenceProducer 2nd try (#2917)
### Motivation:

Adopt `NIOThrowingAsyncSequenceProducer` in NIOFileSystem to reduce code
duplication.

### Modifications:

Adopt `NIOThrowingAsyncSequenceProducer` in NIOFileSystem
`DirectoryEntryProducer` and `FileChunkProducer`.

This change was previously merged and then backed out due to issues
(#2879). The original change is in the first commit, the second commit
contains additional changes.

In the original adoption of `NIOThrowingAsyncSequenceProducer` the code
did not deal with backpressure being applied very well, in some cases
causes hangs.

A key bug was that it was not protected against re-entrant calls to
`produceMore`. Such calls may happen e.g. when the producer has been
asked to pause producing and then resume again before the initial read
had completed. This resulted in overlapping reads and re-ordered data.

This change introduces a new activity state which is protected by a lock
and keeps track of if we are in the critical section to serialize
access.

`DirectoryEntryProducer` performs most of its logic within a lock and so
doesn't seem to be impacted in the same way.

### Result:

No functional changes. Internal changes reduce code duplication.
2024-10-15 10:14:21 +00:00
Clinton Nkwocha 17ebfcd99d [NIOFileSystem] Provide an API to specify allowing unlimited sized reads (#2914)
Motivation:

As described in issue
[#2877](https://github.com/apple/swift-nio/issues/2877), there is no API
available to specify allowing a read of unlimited size.

Modifications:

- Add a new `public static` property, `unlimited`, to `ByteCount`
representing an unlimited amount of bytes.
- Adapt
`ReadableFileHandleProtocol.readToEnd(fromAbsoluteOffset:maximumSizeAllowed:)`
to work with `maximumSizeAllowed` being `ByteCount.unlimited`.

Result:

An API to specify allowing a read of an unlimited size will be
available.
2024-10-11 09:25:17 +00:00
Clinton Nkwocha 611fa094dc Throw error when the max read amount is greater than ByteBuffer can tolerate (#2911)
Motivation:

As described in issue
[#2878](https://github.com/apple/swift-nio/issues/2878), NIOFileSystem
crashes when reading more than `ByteBuffer` capacity.

Modifications:

- Add a new static property, `byteBufferCapacity`, to `ByteCount`
representing the maximum amount of bytes that can be written to
`ByteBuffer`.
- Throw a `FileSystemError` in
`ReadableFileHandleProtocol.readToEnd(fromAbsoluteOffset:maximumSizeAllowed:)`
when `maximumSizeAllowed` is more than `ByteCount.byteBufferCapacity`.

Result:

NIOFileSystem will `throw` instead of crashing.
2024-10-10 09:32:50 +00:00
Clinton Nkwocha 9ff5fddb3d Add convenience conformances to ByteCount (#2909)
Motivation:

Several arithmetic and comparison operations are done with `ByteCount`
using the `bytes` property. Operating on the `ByteCount` type directly
will be more convenient.

Modifications:

- Add `AdditiveArithmetic` and `Comparable` conformances to `ByteCount`.

Result:

The `ByteCount` type can undergo arithmetic and comparison operations.

---------

Co-authored-by: George Barnett <gbarnett@apple.com>
2024-10-09 14:22:05 +00:00
Rick Newton-Rogers 0d3043e050 Revert "Adopt NIOThrowingAsyncSequenceProducer (#2879)" (#2892)
This reverts commit 282f5935cf.

### Motivation:

Repeated testing in linux containers has surfaced issues with the
implementation which require some rethinking of the code, let's revert
it for now and fix it up.

### Modifications:

Revert the adoption commit.

### Result:

The change is backed out.
2024-09-20 10:58:47 +00:00
Rick Newton-Rogers 282f5935cf Adopt NIOThrowingAsyncSequenceProducer (#2879)
### Motivation:

Adopt `NIOThrowingAsyncSequenceProducer` in NIOFileSystem to reduce code
duplication.

### Modifications:

Adopt `NIOThrowingAsyncSequenceProducer` in NIOFileSystem
`DirectoryEntryProducer` and `FileChunkProducer`

### Result:

No functional changes. Internal changes reduce code duplication.
2024-09-13 14:21:23 +01:00
Ali Ali 216975d27b Make FileChunks Sendable (#2871)
Motivation:

`FileChunks` is an `AsyncSequence` so should be `Sendable` otherwise
it's difficult to use.

Modifications:

- Conform `FileChunks` to `Sendable`

Result:

- Resolves https://github.com/apple/swift-nio/issues/2752
2024-09-09 10:23:34 +00:00
Cory Benfield 23e6139e45 Remove symlinks from resources (#2841)
Motivation:

Per @jakepetroules, swift-build copies symlinks as-is into resource
bundles. That means these symlinks are dead when built with swift-build.
There's sort of no point in that.

Modifications:

Remove symlinks, replace with files.

Result:

Privacy info works.
2024-08-13 08:14:22 +01:00
Rick Newton-Rogers bd12191411 Clone files on Darwin rather than copying them (#2823)
### Motivation:

Copying regular files on Darwin was taking more time than it needed to
because it was manually opening files and copying over bites rather than
making use of the system's ability to create CoW clones.

### Modifications:

The primary change is to switch `copyItem` to be backed by Darwin's
`copyfile` method rather than `fcopyfile`. `fcopyfile` ignores the flag
we were passing in to indicate that the file should be cloned if
possible, whereas `copyfile` is a higher-level API which takes this into
account.

This change exposes a `copyfile` wrapper method as a new public
function.

This change also adds a workaround to a seeming compiler bug on channel
options blocking building tests on more recent Xcodes.

### Result:

Copying files on Darwin will be faster.
2024-08-05 12:04:52 +01:00
Matt Hope f0451084bb Provide a default CopyStrategy overload for copyItem. (#2818)
FilesystemProtocol/copyItem has an overload providing the default CopyStrategy

Motivation:

Based on user feedback from #2806
This makes it easier to use, especially when copying files such that it is irrelevant.

Modifications:

Add overload providing (at:to:shouldProceedAfterError:shouldCopyItem:) with CopyStrategy.platformDefault
as the strategy.
Fix a cancellation bug which resulted in a test being flaky.
In addition made the test cover that case reliably to prevent it coming back.

Result:

A simpler and more robust to change API will exist for copyItem()
2024-08-01 09:13:47 +00:00
Matt Hope 022ee1328b FileSystem.copyItem can parallelise directory copy (#2806)
Motivation:

Using some limited parallelism can improved the speed of the copy for very limited increase in cpu use.

In circumstances where the source and/or destination are on a high latency device, such as a network file system,
the resulting speed up can be even more significant.
Providing conservative defaults, while allowing users the ability to control it directly if desired, provides for a faster default and access to user targeted gains in performance. 
The use of parallel by default is considered in keeping with the swift-nio model of concurrent capabilities. 

The parallelism used is restricted because the underlying limited resource for this is highly likely to be limited system file descriptors, rather than the limits of the underlying executor itself, especially on embedded devices with significantly more limited concurrent descriptors.

Modifications:

All copyItem overloads except ```copyItem(sourcePath:destinationPath:shouldProceedAfterError:shouldCopyFile)```
can, and likely will, use concurrent copies when copying directories.

A Newly type ```CopyStrategy``` controls the behaviour, allowing:
* ```parallel(maxDescriptors: Int)```
   * Parallel limited to a maximum number of concurrently open file descriptors.
* ```sequential```
   * The previous behaviour, still asynchronous but only one operation at a time
* ```platformDefault``` 
    * Whatever the API determines the default should be from the prior options

The cancellation semantics of copyItem were previously unclear/undocumented. 
These are now stated and cancellation is tested.

There were some aspects of naming/types on this API which were inconsistent/unclear. Those have been altered to aid clarity.
* Less duplication with the protocol docs
* Consistent use of `item` not `file`
* Use DirectoryEntry for the source in both ```shouldXxx``` callbacks

NIOFileSystem package status remains unchanged, it is still _NIOFileSystem with the semantics that entails.

Result:

For any use of the following functions on FileSystemProtocol, when backed by FileSystem:

- ```copyItem(*)```:

The shouldCopyItem check happens before the internal FileSystem "do I know how to copy this sort of FileType" check. This makes the code a little simpler, but the desire is to allow consuming code to filter out anything unexpected if they like without needing to trap errors.

- ```copyItem(sourcePath:destinationPath)```:

Depending on the platform this will become parallel, users on MacOS, Linux and Windows will have up to 4 concurrent file system operations at once.
Empirical testing on a MacBook pro with a significant dense directory hierarchy of 12 GiB had performance improvements of ~50% reduction in elapsed time for CPU usage increases below the noise floor of the testing

- ```copyItem(sourcePath:destinationPath:shouldProceedAfterError:shouldCopyFile)```:
When migrating from this to ```copyItem(sourcePath:destinationPath:copyStrategy:shouldProceedAfterError:shouldCopyItem)```care should be taken to ensure the should callbacks are safe to use in different concurrency domains, or that CopyStrategy.sequential is explicitly stated.
The backward compatibility shim provided does this by default.
2024-07-29 11:14:10 +01:00
finagolfin 4feff3c2f6 Use the new Android overlay and Bionic module from Swift 6 (#2784)
Motivation:

Get this repo building again for Android with the new overlay

Modifications:

- Import the new module or overlay wherever `Glibc` is used
- Keep this repo building with Swift 5 by duplicating some declarations

Result:

All the same tests keep passing on my Android CI, finagolfin/swift-android-sdk#158
2024-07-22 09:58:09 +00:00
Franz Busch c9756e1083 Adopt swift-format (#2794)
* Apply formatting

* Apply no block comments rule

* Apply OmitExplicitReturns

* Apple OnlyOneTrailingClosureArgument

* Apply NoAssignmentInExpressions

* Fix up DontRepeatTypeInStaticProperties lint errors

* Apply `OrderedImports`

* Apply `ReplaceForEachWithForLoop`

* format file

* Enable the formatting pipeline

* Adopt `AmbiguousTrailingClosureOverload`

* Fix license header

* Fix format check

* Fix `EndOfLineComment`

* Fix CI

* Adapt CI script to check if changes when running formatting

* Separate lint and format into to steps

* Fix format

* Adopt `UseEarlyExits`

* Revert "Adopt `UseEarlyExits`"

This reverts commit d1ac5bbe12.
2024-07-19 11:48:17 +02:00
Franz Busch 9730938793 [GHA] Documentation check (#2764)
# Motivation

Next up replacing the documentation check.

# Modification

This moves the current approach of the script into a GH action. I tried just running the documentation check against all targets but that also results in warnings from downstream deps in their docs to show up.

I also fixed up some new errors that appeared since our current pipeline was running on 5.8.

# Result

Next CI job migrated to GHA
2024-07-04 16:21:18 +01:00
Rick Newton-Rogers 41f66948e1 fix link to NIOFileSystem from NIO index page (#2747)
Motivation:

The existing link to NIOFileSystem docs 404's

Modifications:

Speculative fixes because getting any links to work locally is
challenging.

* rename `NIOFileSystem.md` -> `index.md` in line with other modules
* modify the link on the NIO index page to reference `_NIOFileSystem`
  local experiments suggest it might change the form of the generated
URL to where the docs can be found
(https://swiftpackageindex.com/apple/swift-nio/2.67.0/documentation/_NIOFileSystem).

Result:

Hopefully the NIOFileSystem docs link will work
2024-06-21 16:59:46 +01:00
taylorswift 38f6b98c6a convert the NIOFileSystem example code to a Snippet (#2746)
* convert the NIOFileSystem example code to a Snippet

* fix compilation error

* add missing license header

* exclude snippets from soundness.sh
2024-06-21 10:23:18 +01:00
Gustavo Cairo bc161803bb Add API for setting last accessed and last modified file times (#2735)
This PR adds API to set a file's last accessed and last modified times, as well as a `touch()` shorthand that updates both to the current time.

Motivation:

Feature request: https://github.com/apple/swift-nio/issues/2712

Modifications:

This PR adds API to set a file's last accessed and last modified times, as well as a `touch()` shorthand that updates both to the current time.

Result:

Files' last accessed and last modified times can be updated.
2024-06-10 16:58:21 +01:00
George Barnett 9428f62793 Add a fallback path if renameat2 fails (#2733)
Motivation:

'renameat2' can fail with EINVAL if the RENAME_NOREPLACE flag isn't
supported. However, not all kernel versions support this flag which can
result in an error when creating a file 'transactionally'.

Using 'renameat2' only happens on Linux as a fallback when O_TMPFILE
isn't available.

Modifications:

- On Linux, fallback to a combination of 'stat' and 'rename' if 'renameat2' fails with EINVAL.
- Add a couple of tests

Result:

Files can still be created exclusively
2024-05-31 09:30:50 +01:00
George Barnett d8bf55d693 Add a version of 'write' for 'ByteBuffer' (#2730)
* Add a version of 'write' for 'ByteBuffer'

Motivation:

At the moment 'WritableFileHandleProtocol' is in terms of
`some Sequence<UInt8>`. To use a `ByteBuffer` users must pass in the
readable view of the buffer, which is inconvenient.

Modifications:

- Add an extension to `WritableFileHandleProtocol` which takes a
  `ByteBuffer`.

Result:

Easier to use API

* fix docs
2024-05-29 14:59:06 +01:00
George Barnett 9f63b12a05 Imrprove rename error (#2731)
Motivation:

The name of the syscall used in errors for all rename calls is "rename".
However, this isn't always correct, in some cases "renamex_np" is used,
and in others "renameat2" is used.

Modifications:

- Allow the name of the syscall to be provided to the rename error
- Use the correct syscall name

Result:

Better errors
2024-05-29 14:17:52 +01:00
George Barnett 4612941246 Remove storage indirection for FileSystemError (#2726)
Motivation:

Existentials are boxed if they are wider than 24 bytes. A number of
value types in NIO are implemented with storage classes so that the
alloaction is only paid for once. However, existential errors are
treated differently, they are unconditionally boxed. Implementing errors
with storage classes therefore introduces an unnecessary allocation.

Modifications:

- Remove the storage class for FileSystemError
- Remove the copy-on-write test

Result:

Fewer allocations
2024-05-23 12:58:59 +01:00
George Barnett 29e832adda Replace 'R' with 'Result' (#2709)
Motivation:

Single letter names are discouraged but are used in a handful of places
in NIOFileSystem.

Modifications:

- Replace 'R' with 'ReturnType' where appropriate

Result:

Clearer APIs
2024-04-29 11:01:17 +01:00
George Barnett 8c3135b7d4 Add 'withTemporaryDirectory' (#2708)
Motivation:

NIOFileSystem can create the path of a temporary directory but doesn't
offer any API to create and then remove a directory.

Modifications:

- Add `withTemporaryDirectory`

Result:

- Users can get scoped access to a temporary directory which is
  subsequently removed for them
- Resolves #2664
2024-04-26 01:39:06 -07:00
George Barnett f2f4ce8be7 Add ByteBuffer support to BufferedWriter (#2707)
Motivation:

The `BufferedWriter` in `NIOFileSystem` has API in terms
of `some Sequence<UInt8>`, meaning that you need to pass
`byteBuffer.readableBytesView` which is a bit inconvenient.

Modifications:

- Add overloads which allow you to pass `ByteBuffer` directly
- Remove redundant availability guards; they are already applied to the
  type

Result:

- Better API for users
- Resolves #2662
2024-04-26 09:02:57 +01:00
Peter Adams d3bdffd5e4 Remove surplus Sendable requirements from FileSystem with methods (#2706)
Motivation:

Many of the filesystem with methods have a requirement that the
result type is sendable.  In most cases this is not required as
the result is not shared or sent.

Modifications:

Remove sendable requirement for result types where it is not required.

Result:

Users will not have to make so many types sendable.
2024-04-24 10:36:03 +01:00
George Barnett fa540cf39b Add privacy manifest (#2695)
Motivation:

NIOPosix and NIOFileSystem use stat(2) (or some variation of it). These
are "required reason APIs" meaning that their usage and reason must be
declared in a privacy manifest in order to be submitted to the App Store.

Modifications:

- Add a privacy manifest to NIOPosix and NIOFileSystem

Result:

Apps using NIO won't be rejected from App Store submission for missing
privacy manifests.
2024-04-17 02:48:03 -07:00