ero
Client/Server communication with Named Pipes
Most relevant code: https://gist.github.com/just-ero/a9bb60192a7cc090cb9055dc39770139
Context: I'm reading some information from Mono-based processes (mainly Unity games). For this, I use injection to call the Mono API. I have a client sending request codes and payloads to the server in the injected DLL, which sends response payloads.
Unfortunately, I feel like I've made quite some missteps in designing this process. For example:
- I cannot send a "failure" response; I simply send a response payload with default values,
- I cannot log,
- Request codes are not tightly coupled with their respective request payloads,
- When the client side does not shut down gracefully, the server side does not shut down (because
IsConnected
is never set to false
),
- The server library has to implement the loop for listening manually, I'd like that to be part of the server class itself.
In general, I feel like I went a bit too far with the amount of inheritance I use for the servers. I abstracted the servers so much that I only return payloads instead of result-type values (even though I do have a Result
type).
I would like some help in making this whole system more robust and more intuitive to use and expand upon. I would like a way to add logging (ideally in the form [ServerName] [Method] Actual Log
). I would like to shut down (or halt) the server when the client does not shut down gracefully. And I would like someone to look over my ApiSerializer
class to spot anything that can be written better. The entire way I exchange data feels very opaque and convoluted (I even get confused myself).
I'm on .NET Standard 2.0 for all of this, so a lot of features simply aren't available to me.17 replies
Avalonia app with WASM-based UI-plugins; looking to bounce some ideas around
Hey everyone.
I'm currently working on a plugin system as a side project to my main Avalonia app. The plugins are meant to be compiled WASM core modules and my app will consume them. The idea is to provide a sandboxed environment that any language (that compiles valid WASM core modules) can interact with. This is to allow developers some freedoms in what language they can choose to build the plugins.
Interop between the app and the plugin happens via Extism, a WASM plugin<->host service available for many languages. It allows for the following:
1. Sending packages from and to the plugin
- Extism can allocate a block of memory to place the data in, which is then read by the other side
- This can include any JSON-serialized object, which is then deserialized on the other side
- I have not found (or not checked enough for) a way to send unmanaged structs without serializing
2. Plugins can import and export unmanaged methods
- The app can define unmanaged callbacks, which the plugin can then
DllImport
and call at any time (with some limited arguments)
- The plugin must define some expected exports ([UnmanagedCallersOnly]
) that the app will then call to get certain data
These plugins should now gain the ability to draw on and update the UI of my app.
For some context on that: each plugin gets a dedicated slot on my app. One whole grid row that spans the entire width of the app. The height is determined by the content that the plugin wants to present (or a fixed height, if provided).48 replies
❔ Lazily evaluating Dictionary in update loop with good performance
Situation
I have an update loop which receives some data which is Dictionary-like. Due to a version difference, I receive two types of data. The receiving of this data is not a concern and is relatively cheap.
The two types of data I receive are as follows:
- an array of type
(TKey, TValue)[]
,
- two arrays of types TKey[]
and TValue[]
.
I cannot change these input types (no, I cannot change the array of tuples to an array of KeyValuePair<TKey, TValue>
s).
I know with certainty that the keys are unique, and I know with certainty that they map to exactly one value.
Goal
I want to use this received data just like a Dictionary (an IReadOnlyDictionary<TKey, TValue>
to be precise) without actually building the Dictionary the moment I receive it.
By this I mean, I do not want to populate a Dictionary<TKey, TValue>
with the data, which may be quite large. Doing this would potentially delay the update loop unnecessarily (not actually needing all the data, since only a selection of it will be accessed).
Problem
I can safely have two types of implementations for the two different types of data received.
The issue now is making accesses performant (like the hashing in Dictionaries usually is).
My current idea is the naïve way of making the evaluation linear and caching anything we've already seen. For the ContainsKey implementation, it may be possible to implement a HashSet<TKey>
. This, however, would add an extra allocation, would need to do potentially unnecessary computation, and would require some pretty bad logic for the tuple array data.
I'm simply not sure how to implement this very well such that the lazy evaluation is not simply linear with a cache. Any ideas?102 replies
❔ Creating a "Lazy" Factory with a Fluent API
I'm looking to create a kind of factory, which creates commands instead of the actual results. The results are then conditionally returned upon a call to the factory's
Run()
or Execute()
method. The reason for the "laziness" of the factory is that executing one of these commands may fail (TryExecute()
). This command is then skipped (the failure may be logged) and tried again later, at which point it may no longer fail.
Assume these result objects;
These objects are all "created" differently (as in, they have different constructor parameters), meaning the factory must also have MakeFoo<T>
, MakeBar<T>
, and MakeQux
.
But unfortunately, that's not it. All implementations of FooBase
take an instance of IFoo
as a sort-of parent. This can be nested infinitely. Let's assume something like this;
This means that the factory needs some way to create a parent which then has at least 1 or more children.
I also want to modify some of the objects' properties fluently;
Potential implementations I've considered use a setup such as this;
79 replies
Creating and using an incremental source generator
I wanna create an incremental source generator for my web API project, but I cannot for the life of me understand how to create a source generator at all. I'm even having a hard time understanding the documentation that does exist. Is there anyone that's able to help?
I have a pretty clear idea of what I wanna do: I have a collection of HTTP endpoints in one class, which get turned into controllers, commands, and DTOs.
UserEndpoints.g.cs
47 replies
❔ Creating a backend in .NET
Hi!
I have absolutely zero knowledge about web development, databases, or making any kinds of web requests. Basically, I'm a complete noob when it comes to literally anything web-related (and I know databases aren't necessarily web, but you get the idea).
I would like to build a backend for a website idea that's already pretty big on paper. I have a lot of ideas, have a lot of thoughts about how things should work, I just can't create it.
I was wondering if there are any very beginner friendly, modern tutorials on this stuff? Preferrably videos, as I have a hard time focussing on reading a lot.
If I should go into any more detail, let me know.
1423 replies
How to handle depending on a library which is not available as a NuGet?
I would like to use a library which is open source on GitHub on my own repo. My problem is in handling how to supply that library to people who clone my repo to contribute.
How do I do this?
3 replies
Need help creating a small installer
Using Spectre.Console, I wanna create a really small console app which simply downloads Trace Spy (https://github.com/smourier/TraceSpy), a custom config for it, and a font to go with it (
Cascadia Code
).
I just need some guidance on how to use Spectre, and some insights into best practices and the like. I'll also need a lot of help getting progress bars to work, as well as unzipping and installing the font for the user.124 replies
Progress bar in console app to show download progress
Wanting to create a very simple console application (.NET 7) which downloads a few files and installs them on the user's machine (less "install" and moreso "place a self-contained executable in a directory they choose").
What're my options to create a progress bar for the download process?
15 replies
Optimizing some string manipulation
I want to both substring an input string at the last occurrence of
'/'
and normalize it into only alphanumeric (a-z
, A-Z
, 0-9
) characters, turning any characters unable to be normalized (meaning characters with diacritics turning into their non-diacritic versions (ä
-> a
)) into _
.
Here's what I've got so far;
However, this is hardly faster than using Substring
and Normalize
(with some custom code involving CharUnicodeInfo.GetUnicodeCategory
).
Any ideas?18 replies
Fast look-up algorithms
I'm looking to use a sort of cache of objects which are stored each with a unique key.
Currently, I do this simply using a
Dictionary<TKey, TValue>
. This is to prevent having to fetch the items anew, when I can simply get them from that cache.
My question is, what are some quicker and more efficient collections or algorithms to use for storing pairs of keys and values and fetching them when needed? (Obviously the logic to "refresh" the cache will run when an item cannot be found.)22 replies
Parsing a string into a Vector of bytes most efficiently
Given a string with an even amount of characters, what's the most efficient way to parse that into a
Vector<byte>
along with another Vector<byte>
of bit masks?
A sample input is 12 34 ?? 78 87 ?5 ?3 21
-- these are meant to be hex bytes -- which would get turned into < 0x12 0x34 0x00 0x78 0x87 0x05 0x03 0x21 >
for the values, and < 0xFF 0xFF 0x00 0xFF 0xFF 0x0F 0x0F 0xFF >
for the masks.
Currently I'm doing the input.Length % 2 != 0
check first, of course, followed by Regex.Matches(input, @"..").Select(match => match.Value).ToList();
.
From here I do this to parse all of the bytes;
Obviously the big one is using Regex. Any ideas?11 replies