What's the usage of StackExchange.Redis on redis cluster mode - c#

This is using stackexchange.redis v1.1.603, .net 4.6, console application.
Here is my codes:
using System;
using System.Collections.Generic;
using StackExchange.Redis;
namespace RedisClusterTesting
{
class Program
{
static void Main(string[] args)
{
string ip = "192.168.1.20:30001,192.168.1.20:30002,192.168.1.20:30003,resolvedns=1";
var conf = ConfigurationOptions.Parse(ip);
conf.CommandMap = CommandMap.Create(new HashSet<string> {
"INFO", "CONFIG", "CLUSTER","PING", "ECHO", "CLIENT"
}, false);
using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect(conf))
{
var db = conn.GetDatabase();
Do(db);
}
Console.ReadKey();
}
private static void Do(IDatabase db)
{
/*here throws MOVED Exception:MOVED 12182 192.168.1.20:30003*/
db.StringSet("foo", "changed");
Console.WriteLine("foo now:" + db.StringGet("foo").ToString());
}
}
}
Always show the message "MOVED: 12586[192.168.1.20:30003]".
I search all the offcial document and on the Internet, can't find the right answer. It's OK while I use redis-cli.
How to fix this?Do I need process the exception in my code?If, how?

Seems like you may be running into this issue: https://github.com/StackExchange/StackExchange.Redis/issues/248. If you put a 1 second sleep between your Connect() call and your Do() call, I would guess that you will see the issue go away.

Related

Get Azure VM PowerState in C#/dotnet using Azure.ResourceManager

I want to get the PowerState (on/off/restarting, etc.) of a known Azure VM instance in a C#/dotnet application using Azure.ResourceManager (not PowerShell, not CLI, not REST, not using any deprecated Fluent approach).
I can do it successfully with REST so I know the underlying VM InstanceView data exists, but for this application REST will not pass muster.
I am using the following code; vm.Data.Name comes back as expected, but am getting null responses from InstanceView.Statuses.
I haven't been able to find any helpful MSFT documentation, except for old, deprecated approaches.
Does anyone know how to get PowerState via Azure.ResourceManager, or why I am getting NULL back?
Thanks!!
[code sample updated below on 1/16/23, changed auth approach, InstanceView still returning NULL]
using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Resources;
namespace Test
{
public class Program
{
public static async Task ListAllVms()
{
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();
string rgName = "redacted";
ResourceGroupResource resourceGroup = await subscription.GetResourceGroups().GetAsync(rgName);
VirtualMachineCollection vmCollection = resourceGroup.GetVirtualMachines();
AsyncPageable<VirtualMachineResource> response = vmCollection.GetAllAsync();
await foreach (VirtualMachineResource vm in response)
{
Console.WriteLine(vm.Data.Name);
foreach (InstanceViewStatus istat in vm.Data.InstanceView.Statuses)
{
Console.WriteLine("\n code: " + istat.Code);
Console.WriteLine(" level: " + istat.Level);
Console.WriteLine(" displayStatus: " + istat.DisplayStatus);
}
}
}
public static async Task Main(string[] args)
{
await ListAllVms();
}
}
}
After reproducing from my end, I could able to achieve this using vm.Get().Value.InstanceView().Value.Statuses[1].DisplayStatus. Below is the complete code that worked for me where I list all the vm present in my resource group and get the statuses of it.
using System;
using System.Threading.Tasks;
using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Resources;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
ArmClient armClient = new ArmClient(new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions() { TenantId = "<YOUR_TENAT_ID>" }));
SubscriptionResource subscriptionResource = await armClient.GetDefaultSubscriptionAsync();
string rgName = "<YOUR_RESOURCE_GROUP>";
ResourceGroupResource resourceGroupResource = await subscriptionResource.GetResourceGroups().GetAsync(rgName);
VirtualMachineCollection vmCollection = resourceGroupResource.GetVirtualMachines();
// Lists all virtual machines
AsyncPageable<VirtualMachineResource> vmList = vmCollection.GetAllAsync();
Console.WriteLine("Listing");
await foreach (VirtualMachineResource vm in vmList)
{
Console.WriteLine(vm.Data.Name);
Console.WriteLine(vm.Get().Value.InstanceView().Value.Statuses[1].DisplayStatus);
}
}
}
}
output:

SnmpSharpNet.SnmpException: 'Request has reached maximum retries.'

I was researching SNMPv3 for an internship and I got this code from snmpsharp.net (I couldn't show all of the code stackoverflow wouldn't let me)
using System;
using System.Net;
using SnmpSharpNet;
namespace SharpGetV3
{
class MainClass
{
public static void Main(string[] args)
{
IpAddress ipa = new IpAddress("192.168.1.5");
UdpTarget target = new UdpTarget((IPAddress)ipa);
SecureAgentParameters param = new SecureAgentParameters();
if (!target.Discovery(param))
{
Console.WriteLine("Discovery failed. Unable to continue...");
target.Close();
return;
}
I couldn't get past the line
if(!target.Discoverey(param))
It gives me the error SnmpSharpNet.SnmpException: 'Request has reached maximum retries.'.What could be the cause of this?I could run SNMPv2 get requests just fine.Apologies if I can't answer your questions I'm still trying to understand how all this works.

C# ScrapySharp 'System.Net.CookieException: 'The 'Name'='HttpOnly, NID' part of the cookie is invalid.'

So i'm facing an unexpected issue with my code. For some reason, I am unable to download & print the links out of my Google search... Help is much appreciated as I'm really not sure what is going on here... I am also using the DotNET SDK
using System;
using System.Threading.Tasks;
using ScrapySharp;
using ScrapySharp.Extensions;
using ScrapySharp.Network;
using static System.Console;
namespace Test
{
class Program
{
static async Task Main(string[] args)
{
var query = "scrapysharp";
Console.WriteLine($"Searching '{query}' on google");
var browser = new ScrapingBrowser();
browser.UseDefaultCookiesParser = false;
var resultsPage = await browser.NavigateToPageAsync(new Uri($"https://www.google.fr/search?q={query}"));
Console.WriteLine($"Results");
foreach (var link in resultsPage.Html.CssSelect("h3.r a"))
{
Console.WriteLine($"- {link.InnerText}");
}
}
}
Error:
System.Net.CookieException: 'The 'Name'='HttpOnly, NID' part of the cookie is invalid.'
I was facing the same issue, the quick workaround for me was bellow one line code.
browser.IgnoreCookies = true;
Leave everything else as is, add this line after the line where you are creating browser object and try it out.

C#: How to use Service References in Visual Studio 2015 (Move from Linqpad)

I would like to migrate a C# Program to Visual Studio. I'm fairly new working with C#, however I could have learned some stuff in Linqpad.
In Linqpad I imported my dll as an additional Reference and could use it. The dll was generated with:
"wsdl http://localhost/WebService.asmx"
and
"csc /t:library WebService.cs"
Linqpad Code which worked was like:
WebService ws = new WebService();
void Main()
{
try
{
var connect = ws.Logon("localhost", Port, "", "username", "password);
var morefiles = false;
// do other stuff....
do
{
var results = ws.search(connect, "Culture", "Culture", searchCondition, morefiles);
} while (morefiles == true);
}
catch (Exception x)
{
Console.WriteLine(x.Message);
Console.WriteLine(x.StackTrace);
}
finally {
Console.WriteLine("Search done");
}
}
Now, I would like to use it in Visual Studio. In VS I imported it as a Service References with the given URL, and it showed me the necessary stuff.
Now when I try to use it in my code I get an error message which tells me:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Testproject.WebService;
namespace Testproject
{
class Program
{
static void Main(string[] args)
{
WebService ws = new WebService();
Console.WriteLine("Test");
Console.ReadKey();
}
}
}
The error message is in the line:
WebService ws = new WebService();
It shows me this error message:
WebService is a 'namespace' but is used like a 'type'
I also found out, that "Logon" which I used in Line 6 in Linqpad is in:
WebService.WebServiceSoap
However, if I change the line in:
WebService.WebServiceSoap ws = new WebService.WebServiceSoap();
I also get an error message:
Cannot create an instance of the abstract class or interface
I tried different combinations also, but I don't exactly no, what can be wrong. Can you help me?

C# IO Reading and Writing file in use error

I have a library that handles reading and writing a cache file. This library is used by a Windows Service and several instances of a console application on the same machine. The console application runs when a user logs in.
I am getting occasional IO errors saying the cache file is in use by another process. I assume that collisions are occurring between the different application instances and service trying to read and write at the same time.
Is there a way to lock the file when it is in use and force all other requests to "wait in line" to access the file?
private void SaveCacheToDisk(WindowsUser user) {
string serializedCache = SerializeCache(_cache);
//encryt
serializedCache = AES.Encrypt(serializedCache);
string path = user == null ? ApplicationHelper.CacheDiskPath() :
_registry.GetCachePath(user);
string appdata = user == null ? ApplicationHelper.ClientApplicationDataFolder() :
_registry.GetApplicationDataPath(user);
if (Directory.Exists(appdata) == false) {
Directory.CreateDirectory(appdata);
}
if (File.Exists(path) == false) {
using (FileStream stream = File.Create(path)) { }
}
using (FileStream stream = File.Open(path, FileMode.Truncate)) {
using (StreamWriter writer = new StreamWriter(stream)) {
writer.Write(serializedCache);
}
}
}
private string ReadCacheFromDisk(WindowsUser user) {
//cache file path
string path = user == null ? ApplicationHelper.CacheDiskPath() :
_registry.GetCachePath(user);
using (FileStream stream = File.Open(path, FileMode.Open)) {
using (StreamReader reader = new StreamReader(stream)) {
string serializedCache = reader.ReadToEnd();
//decrypt
serializedCache = AES.Decrypt(serializedCache);
return serializedCache;
}
}
}
Sure, you could use a mutex and permit access only when holding the mutex.
You could use a cross-process EventWaitHandle. This lets you create and use a WaitHandle that's identified across processes by name. A thread is notified when it's its turn, does some work, and then indicates it's done allowing another thread to proceed.
Note that this only works if every process/thread is referring to the same named WaitHandle.
The EventWaitHandle constructors with strings in their signature create named system synchronization events.
One option you could consider is having the console applications route their file access through the service, that way there's only one process accessing the file and you can synchronise access to it there.
One way of implementing this is by remoting across an IPC channel (and here's another example from weblogs.asp.net). We used this technique in a project for the company I work for and it works well, with our specific case providing a way for a .net WebService to talk to a Windows Service running on the same machine.
Sample based on the weblogs.asp.net example
Basically what you need to do with the code below is create a Solution, add two Console Apps (one called "Server" and the other called "Client" and one Library to it. Add a reference to the Library to both console apps, paste the code below in and add a reference to System.Runtime.Remoting to both Server & Console.
Run the Server app, then run the client app. Observe the fact that the server app has a message passed to it by the client. You can extend this to any number of messages/tasks
// Server:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
namespace RemotingSample
{
public class Server
{
public Server()
{
}
public static int Main(string[] args)
{
IpcChannel chan = new IpcChannel("Server");
//register channel
ChannelServices.RegisterChannel(chan, false);
//register remote object
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemotingSample.RemoteObject),
"RemotingServer",
WellKnownObjectMode.SingleCall);
Console.WriteLine("Server Activated");
Console.ReadLine();
return 0;
}
}
}
// Client:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using RemotingSample;
namespace RemotingSample
{
public class Client
{
public Client()
{
}
public static int Main(string[] args)
{
IpcChannel chan = new IpcChannel("Client");
ChannelServices.RegisterChannel(chan);
RemoteObject remObject = (RemoteObject)Activator.GetObject(
typeof(RemotingSample.RemoteObject),
"ipc://Server/RemotingServer");
if (remObject == null)
{
Console.WriteLine("cannot locate server");
}
else
{
remObject.ReplyMessage("You there?");
}
return 0;
}
}
}
// Shared Library:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
namespace RemotingSample
{
public class RemoteObject : MarshalByRefObject
{
public RemoteObject()
{
Console.WriteLine("Remote object activated");
}
public String ReplyMessage(String msg)
{
Console.WriteLine("Client : " + msg);//print given message on console
return "Server : I'm alive !";
}
}
}
Check out the TextWriter.Synchronized method.
http://msdn.microsoft.com/en-us/library/system.io.textwriter.synchronized.aspx
This should let you do this:
TextWriter.Synchronized(writer).Write(serializedCache);

Categories

Resources