How to use EC2 api to tell instance status? - c#

In the AWS console, you can see what instances are online, what are shutting down, and what are shut down. I'm trying to replicate this functionality in my application, but EC2 api doesn't seem to cooperate.
Here's what I'm doing:
DescribeInstanceStatusRequest rr=new DescribeInstanceStatusRequest();
rr.InstanceIds=new List<string>(new[]{instanceId});
var status = ec2.DescribeInstanceStatus(rr);
List<InstanceStatus> statusses = new List<InstanceStatus>();
foreach (var s in status.InstanceStatuses)
{
if (s.InstanceId == instanceId)
{
statusses.Add(s);
}
}
if (statusses.Any())
{
var instanceStatus = statusses.First();
...
}
This works fine when the instance is online, but as soon as I request to shut it down, the instance disappears from the info.
How do I get info for all instances, including those shutting down, shut down and terminated ones?

By default, DescribeInstanceStatus only captures instances that are running. You can set the property IncludeAllInstances in the request to true to change this. From the documentation:
IncludeAllInstances
When true, includes the health status for all instances. When false,
includes the health status for running instances only.
Default: false
Code example:
DescribeInstanceStatusRequest rr = new DescribeInstanceStatusRequest()
{
IncludeAllInstances = true
};
Reference:
AWS Documentation - DescribeInstanceStatusRequest

Related

Embedded Nancy not listening

I read a couple of related questions which had an issue with accessing nency from a remote computer. However, I am unable to access nancy from my own pc.
Here is my code:
class Program
{
static void Main(string[] args)
{
HostConfiguration hostConfigs = new HostConfiguration();
//hostConfigs.RewriteLocalhost = true;
hostConfigs.UrlReservations.CreateAutomatically = true;
using (var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234")))
{
host.Start();
Console.WriteLine("Running on http://+:1234");
Console.WriteLine(host.ToString());
}
Console.ReadKey();
}
}
public class HelloModule : NancyModule
{
public HelloModule()
{
Get["/"] = parameters => Response.AsJson("Success");
Get["/nancy"] = parameters => Response.AsJson("Success");
}
}
}
I am administrator on my PC and I do not get any exception. If I type http://localhost:1234 or http://127.0.0.1:1234 to my browser (with /nancy and without) I would expect a response. However, I do net get any reponse. Further, in the list produced with netstat -ano I do not see any process listing on port 1234. I downloaded the latest version of nancy via nuget.
Do you have any idea?
The following line should work as expected:
var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234"))
But what happens with a using statement, is that anything specified between ( and ) (simply put) is disposed after the closing brace (}) of the same using statement. So what is actually happening is, the host gets created, is started, and is disposed right after it printed some lines to the console.
Simply put, move the ReadKey call inside the using statement. There it will wait until a key is pressed, and the host will be disposed after that event has occurred.

Not able to create second queue by code

I'm creating two queues in code if they don't already exist at Page_Load. The code runs fine for the first queue, but failed to set its Authenticate property on the second queue. I'm running Visual Studio as Administrator and can create those queues with the MSMQ UI. Both queues were created when I look in the UI, but the second one didn't have the property set.
if (MessageQueue.Exists(path1) == false)
{
var q = MessageQueue.Create(path1, true);
q.Authenticate = true;
}
if (MessageQueue.Exists(path2) == false)
{
var q = MessageQueue.Create(path2, true); // <-- didn't fail here
q.Authenticate = true; // <-- failed here
}
Error message:
The queue does not exist or you do not have sufficient permissions to perform the operation.

WCF TimeoutException despite stepping through showing successful return

I have two self hosted services running on the same network. The first is sampling an excel sheet (or other sources, but for the moment this is the one I'm using to test) and sending updates to a subscribed client.
The second connects as a client to instances of the first client, optionally evaluates some formula on these inputs and the broadcasts the originals or the results as updates to a subscribed client in the same manner as the first. All of this is happening over a tcp binding.
My problem is occuring when the second service attempts to subscribe to two of the first service's feeds at once, as it would do if a new calculation is using two or more for the first time. I keep getting TimeoutExceptions which appear to be occuring when the second feed is subscribed to. I put a breakpoint in the called method on the first server and stepping through it, it is able to fully complete and return true back up the call stack, which indicates that the problem might be some annoying intricacy of WCF
The first service is running on port 8081 and this is the method that gets called:
public virtual bool Subscribe(int fid)
{
try
{
if (fid > -1 && _fieldNames.LeftContains(fid))
{
String sessionID = OperationContext.Current.SessionId;
Action<Object, IUpdate> toSub = MakeSend(OperationContext.Current.GetCallbackChannel<ISubClient>(), sessionID);//Make a callback to the client's callback method to send the updates
if (!_callbackList.ContainsKey(fid))
_callbackList.Add(fid, new Dictionary<String, Action<Object, IUpdate>>());
_callbackList[fid][sessionID] = toSub;//add the callback method to the list of callback methods to call when this feed is updated
String field = GetItem(fid);//get the current stored value of that field
CheckChanged(fid, field);//add or update field, usually returns a bool if the value has changed but also updates the last value reference, used here to ensure there is a value to send
FireOne(toSub, this, MakeUpdate(fid, field));//sends an update so the subscribing service will have a first value
return true;
}
return false;
}
catch (Exception e)
{
Log(e);//report any errors before returning a failure
return false;
}
}
The second service is running on port 8082 and is failing in this method:
public int AddCalculation(string name, string input)
{
try
{
Calculation calc;
try
{
calc = new Calculation(_fieldNames, input, name);//Perform slow creation before locking - better wasted one thread than several blocked ones
}
catch (FormatException e)
{
throw Fault.MakeCalculationFault(e.Message);
}
lock (_calculations)
{
int id = nextID();
foreach (int fid in calc.Dependencies)
{
if (!_calculations.ContainsKey(fid))
{
lock (_fieldTracker)
{
DataRow row = _fieldTracker.Rows.Find(fid);
int uses = (int)(row[Uses]) + 1;//update uses of that feed
try
{
if (uses == 1){//if this is the first use of this field
SubServiceClient service = _services[(int)row[ServiceID]];//get the stored connection (as client) to that service
service.Subscribe((int)row[ServiceField]);//Failing here, but only on second call and not if subscribed to each seperately
}
}
catch (TimeoutException e)
{
Log(e);
throw Fault.MakeOperationFault(FaultType.NoItemFound, "Service could not be found");//can't be caught, if this timed out then outer connection timed out
}
_fieldTracker.Rows.Find(fid)[Uses] = uses;
}
}
}
return id;
}
}
catch (FormatException f)
{
Log(f.Message);
throw Fault.MakeOperationFault(FaultType.InvalidInput, f.Message);
}
}
The ports these are on could change but are never shared. The tcp binding used is set up in code with these settings:
_tcpbinding = new NetTcpBinding();
_tcpbinding.PortSharingEnabled = false;
_tcpbinding.Security.Mode = SecurityMode.None;
This is in a common library to ensure they both have the same set up, which is also a reason why it is declared in code.
I have already tried altering the Service Throttling Behavior for more concurrent calls but that didn't work. It's commented out for now since it didn't work but for reference here's what I tried:
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior
{
MaxConcurrentCalls = 400,
MaxConcurrentSessions = 400,
MaxConcurrentInstances = 400
};
host.Description.Behaviors.RemoveAll<ServiceThrottlingBehavior>();
host.Description.Behaviors.Add(stb);
Has anyone had similar issues of methods working correctly but still timing out when sending back to the caller?
This was a difficult problem and from everything I could tell, it is an intricacy of WCF. It cannot handle one connection being reused very quickly in a loop.
It seems to lock up the socket connection, though trying to add GC.Collect() didn't free up whatever resources it was contesting.
In the end the only way I found to work was to create another connection to the same endpoint for each concurrent request and perform them on separate threads. Might not be the cleanest way but it was all that worked.
Something that might come in handy is that I used the svc trace viewer to monitor the WCF calls to try and track the problem, I found out how to use it from this article: http://www.codeproject.com/Articles/17258/Debugging-WCF-Apps

EasyNetQ. Advanced API - Publish does not produce response on RabbitServer

Looking at EasyNetQ as replacement for our current library for MQ communication.
For Testing im trying to simply publish a number of messages to an exchange, using a custom naming strategy.
My method for publishing is in t he small test method below>
public void PublishTest()
{
var advancedBus = RabbitHutch.CreateBus("host=localhost;virtualHost=Test;username=guest;password=guest;").Advanced;
var routingKey = "SimpleMessage";
// declare some objects
var queue = advancedBus.QueueDeclare("Q.TestQueue.SimpleMessage");
var exchange = advancedBus.ExchangeDeclare("E.TestExchange.SimpleMessage", ExchangeType.Direct);
var binding = advancedBus.Bind(exchange, queue, routingKey);
var message = new SimpleMessage() {Test = "HELLO"};
for (int i = 0; i < 100; i++)
{
advancedBus.Publish(exchange, routingKey, true, true, new Message<SimpleMessage>(message));
}
advancedBus.Dispose();
}
The problem is that even thou the Exchange and Queue is created, and bound proper, publishing does not produce anything.
No messages hit the queue.
The graph in the Rabbit MQ management interface does not even show any activity on the exchange.
Am i missing something here? The code is basically taken straight from the documentation.
If im using the simple bus and simply just publish, an exchange is created and i can see via the management interface, that messages are being published.
Since the simple bus uses the advanced API to publish i assume that it is a setup issue that i am missing.
I hope someone can bring some insight:-)
/Thomas
I finally tracked down what was causing the problem.
It turns out that setting the parameter: immediate to true will cause the systems to throw exceptions.
the paramters is apparently not supported any more in the RabbitMQ client, see the discussion here: https://github.com/mikehadlow/EasyNetQ/issues/112
So the code below works just fine, mark the change from true to false in the publish method:
public void PublishTest()
{
var advancedBus = RabbitHutch.CreateBus("host=localhost;virtualHost=Test;username=guest;password=guest;").Advanced;
var routingKey = "SimpleMessage";
// declare some objects
var queue = advancedBus.QueueDeclare("Q.TestQueue.SimpleMessage");
var exchange = advancedBus.ExchangeDeclare("E.TestExchange.SimpleMessage", ExchangeType.Direct);
var binding = advancedBus.Bind(exchange, queue, routingKey);
var message = new SimpleMessage() {Test = "HELLO"};
for (int i = 0; i < 100; i++)
{
advancedBus.Publish(exchange, routingKey, true, false, new Message<SimpleMessage>(message));
}
advancedBus.Dispose();
}

Programmatically get site status from IIS, gets back COM error

I am trying to programmatically get my site status from IIS to see if it's stopped, but I kept getting the following error,
The object identifier does not represent a valid object. (Exception from HRESULT: 0x800710D8)
The application is using ServerManager Site class to access the site status. Here is the code,
//This is fine, gets back the site
var serverManager = new Microsoft.Web.Administration.ServerManager(ConfigPath);
var site = serverManager.Sites.FirstOrDefault(x => x.Id == 5);
if (site == null) return;
var appPoolName = site.Applications["/"].ApplicationPoolName;
//error!
var state = site.State;
I've test with static site to isolate the issue, making sure that the site is up and running, all configuration are valid, point to the valid application pool...etc.
Let me know if you need more details. Is it the COM thing?
I figured out where the problem is. Basically, there are two parts to the Server manager, the first part of the server manager allows you to read site details from configuration file, which is what I've been doing above. The problem with that is you will only able get the information that's in file and site state is not part of it.
The second part of the Server Manager allows you to connect to the IIS directly and it does this by interacting with the COM element. So what I should be doing is this:
ServerManager manager= ServerManager.OpenRemote("testserver");
var site = manager.Sites.First();
var status = site.State.ToString() ;
I had a similar problem but mine was caused by the delay needed to activate the changes from the call to CommitChanges on the ServerManager object. I found the answer I needed here:
ServerManager CommitChanges makes changes with a slight delay
It seems like polling is required to get consistent results. Something similar to this solved my problem (I got the exception when accessing a newly added application pool):
...
create new application pool
...
sman.CommitChanges();
int i = 0;
const int max = 10;
do
{
i++;
try
{
if (ObjectState.Stopped == pool.State)
{
write_log("Pool was stopped, starting: " + pool.Name);
pool.Start();
}
sman.CommitChanges();
break;
}
catch (System.Runtime.InteropServices.COMException e)
{
if (i < max)
{
write_log("Waiting for IIS to activate new config...");
Thread.Sleep(1000);
}
else
{
throw new Exception(
"CommitChanges timed out efter " + max + " attempts.",
e);
}
}
} while (true);
...

Categories