microsoft / garnet

Garnet is a remote cache-store from Microsoft Research that offers strong performance (throughput and latency), scalability, storage, recovery, cluster sharding, key migration, and replication features. Garnet can work with existing Redis clients.
https://microsoft.github.io/garnet/
MIT License
10.4k stars 526 forks source link

Create "dotnet global tool" packaging to make deployment trivial #774

Closed mgravell closed 2 weeks ago

mgravell commented 2 weeks ago

Feature request type

enhancement

Is your feature request related to a problem? Please describe

Right now, installing and running Garnet is a pain if what you want is just "give me a server"; the getting started guide involves git clone, dotnet restore , dotnet build, dotnet run etc. Which means you need dev tools and a lot of steps - and you need to repeat all that to keep up-to-date. If you're a developer, great! But if you just want a server, this is massively overkill; you want something more like "install, (run command)"

Thought experiment; how about if, from any OS with .NET, it was as simple as:

marc@mgx:~$ garnet-server
garnet-server: command not found
marc@mgx:~$ dotnet tool install --global garnet-server
Skipping NuGet package signature verification.
You can invoke the tool using the following command: garnet-server
Tool 'garnet-server' (version '1.0.35') was successfully installed.
marc@mgx:~$ garnet-server --port 6385
    _________
   /_||___||_\      Garnet 1.0.35 64 bit; standalone mode
   '. \   / .'      Port: 6385
     '.\ /.'        https://aka.ms/GetGarnet
       '.'

* Ready to accept connections

Well, it can be that simple, because: the above works! It also supports simple updates, etc; for example:

marc@mgx:~$ dotnet tool update --global garnet-server
Skipping NuGet package signature verification.
Tool 'garnet-server' was reinstalled with the latest stable version (version '1.0.35').

Describe the solution you'd like

So: I'm proposing that the /main/GarnetServer executable is packaged and uploaded to NuGet as a .NET global tool; this is not complicated; here's how I did the above. The main bits are just:

<PackAsTool>true</PackAsTool>
<ToolCommandName>garnet-server</ToolCommandName>

(although other things like a readme, icon, etc are good practice)

Note:

I have uploaded garnet-server for the purposes of this demonstration; I claim no ownership of this:


If you would like me to prepare a PR to help with this: just let me know what PackageId and ToolCommandName to use. Personally, for simplicity, I would suggest either of (in my preferred order, although it really isn't up to me):

or

The package is the thing used in dotnet tool install --global THIS_BIT_HERE, and the command is the thing the end-user types. The reason I am advocating garnet-server as the command is for parity with redis-server, memurai-server, valkey-server, etc. There's a lot to be said for parity. The brevity is also nice. Note that this contrasts with the existing executable name of GarnetServer.exe; fortunately, the dotnet tool packaging makes this a non-issue, with an abstraction between commands and assemblies. The NuGet package Microsoft.Garnet is already in use as a library (package-reference), and I do not propose changing that at all - hence Microsoft.Garnet.Server as a fallback suggestion for the package.


In unrelated news, you might also like a tool I'm playing with (and plan to improve a lot); this is what made me think of garnet-server:

marc@mgx:~$ dotnet tool install --global resp-cli --version 2.8.23-gd84d0e0788
Skipping NuGet package signature verification.
You can invoke the tool using the following command: resp-cli
Tool 'resp-cli' (version '2.8.23-gd84d0e0788') was successfully installed.
marc@mgx:~$ resp-cli -p 6385
Connecting to 127.0.0.1:6385...
# Server
garnet_version: 1.0.35
redis_version:  7.2.5
redis_mode:     standalone
databases:      16
> ping hello
$ hello
>

Describe alternatives you've considered

No response

Additional context

No response

mgravell commented 2 weeks ago

Note: my hacked-up package does not currently include the extensions that are in /main/GarnetServer (see me vs Garnet).

mgravell commented 2 weeks ago

Open question: if this is approved and implemented; how much of the existing docs/guidance should be updated to reflect usage as a dotnet tool rather than via raw exe usage? And who should do that?

badrishc commented 2 weeks ago

Note: my hacked-up package does not currently include the extensions that are in /main/GarnetServer (see me vs Garnet).

This diff looks perfectly fine. Those extensions were meant as samples rather than APIs that clients might expect.

badrishc commented 2 weeks ago

you might also like a tool I'm playing with

very nice! i think it is about time someone came up with a better client tool than redis-cli :). do you have plans for specific differentiating features yet?

mgravell commented 2 weeks ago

in resp-cli ? a big one for me will be getting it to work with out-of-band messages, however, that might need some advanced console-fu so I can retain the bottom editable line but scroll in new data above it; obviously that won't work with redirected IO, but I wonder if it can work with an interactive console and some magic

(edit: I also described what is basically the -c feature in redis-cli; I should reimplement that, but that isn't a differentiator, if it exists in redis-cli! the biggest reason for this is simply: getting hold of the tool conveniently, especially on Windows)

badrishc commented 2 weeks ago

If you would like me to prepare a PR to help with this: just let me know what PackageId and ToolCommandName to use.

This is a fantastic idea, and we would love to include this simplification. ToolCommandName should remain garnet-server IMHO. We might even consider renaming GarnetServer.exe at some point for consistency?

For PackageId, we own the Microsoft.Garnet.* prefix namespace in NuGet.org, so wondering if we should contine down that road as Microsoft.Garnet.Server. TBH, garnet-server sounds simple and easier to find too. Is there a way for one to redirect to the other?

mgravell commented 2 weeks ago

Active redirect? No. What we can do is (for example) mark garnet-server as deprecated, citing Microsoft.Garnet.Server (or whatever) as the alternate. This should cause an appropriate message to be issued, but it isn't an active redirect AFAIK (we could test it?). Using Microsoft.Garnet.Server or similar makes total sense, and me blocking out garnet-server as an empty stub with a "please go here instead" makes sense to prevent malicious actors squatting it. I also agree there's a certain elegance in simply using garnet-server. Up to you!

badrishc commented 2 weeks ago

OK, sounds great, thanks. Let us go with garnet-server for PackageID as well, as that definitely sounds more in line with tools of this nature. The (brief) doc for how to run as a nuget tool can simply be added as a section to https://github.com/microsoft/garnet/blob/main/website/docs/welcome/releases.md in the PR, and it will automatically update the website. Thanks!