cloudtoid / interprocess

A cross-platform shared memory queue for fast communication between processes (Interprocess Communication or IPC).
MIT License
183 stars 26 forks source link

Got into "System.ArgumentException: The initial count cannot be greater than 32767." while bytesCapacity in options is not #19

Open ColourfulBlack opened 1 year ago

ColourfulBlack commented 1 year ago

Problem description

At first, I import Cloudtoid.Interprocess to my ASP.NET WEB API backend application, every time it run using var publisher = factory.CreatePublisher(options); it got into the exception below:

Unhandled exception. System.ArgumentException: The initial count cannot be greater than 32767. (Parameter 'initialCount')
   at Cloudtoid.Interprocess.Semaphore.MacOS.Interop.CreateOrOpenSemaphore(String name, UInt32 initialCount)
   at Cloudtoid.Interprocess.Semaphore.MacOS.SemaphoreMacOS..ctor(String name, Boolean deleteOnDispose)
   at Cloudtoid.Interprocess.InterprocessSemaphore.CreateReleaser(String name)
   at Cloudtoid.Interprocess.Publisher..ctor(QueueOptions options, ILoggerFactory loggerFactory)
   at Cloudtoid.Interprocess.QueueFactory.CreatePublisher(QueueOptions options)
   ...

I move the code into a vary simple project which just contains a single Program.cs:

using Cloudtoid.Interprocess;
using Microsoft.Extensions.Logging;

var factory = new QueueFactory();
var options = new QueueOptions(
    queueName: "sample-queue", bytesCapacity: 24);// just 24
using var publisher = factory.CreatePublisher(options);

It got into the same exception.

Reproduction

I pushed that simple project to this GitHub repository

Additional information

Cloudtoid.Interprocess version 1.0.175

My OS information:

# uname -a
Darwin hostname.lan 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar  6 20:59:28 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T6000 arm64

My dotnet information:

# dotnet --info
.NET SDK:
 Version:   7.0.203
 Commit:    5b005c19f5

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  13.3
 OS Platform: Darwin
 RID:         osx.13-arm64
 Base Path:   /usr/local/share/dotnet/sdk/7.0.203/

Host:
  Version:      7.0.5
  Architecture: arm64
  Commit:       8042d61b17

.NET SDKs installed:
  7.0.203 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/opt/homebrew/opt/dotnet/libexec]

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
albahari commented 2 months ago

Agreed - this library is completely useless on macOS.

Maybe it hasn't been tested on this platform.

prezaei commented 2 months ago

Thanks for reporting. This was tested on MacOS when it was developed. However, something has changed in the OS and its support of sem_open. Either of you have bandwidth to help and debug? I updated the code to .NET 8 but can't figure out what is up with sem_open. Sees like an arm based issue.

ColourfulBlack commented 2 months ago

Hum...🧐 I see, so it could be some system related issue. And sorry that I couldn't help recently. I will see what I can do when I have some spare time.

albahari commented 2 months ago

I've identified one cause: sem_open fails immediately if the semaphore name is more than 10 characters. With a short name, it gets further, but even then, it doesn't seem to allow two processes to work with the same semaphore.

Also, it seems that sem_open works only on the default thread - this might be a macOS limitation.