Do I need to close MongoDB client? - mongodb

I'm working on a discord bot, but I'm not sure if I need to close the MongoClient with:
client.close()
The issue I have is that I'm returning some data from a collection, and obviously, I can't close the client after I return something.
If I need to close the client, what's the best way of doing it? At the moment, I have a discord command that returns something.
def get_queue_info(queue):
if queue.isdigit():
queue = int(queue)
return db['Groups'].find_one({"order":queue})
else:
return db['Groups'].find_one({"name":str(queue).upper()})
#obviously, this won't work
#mongo.close()
My bot is executing commands pretty slowly, but I'm not sure if it's because of not closing

You don't need to close the connection. Pymongo manages the connection so there is no need to tidy it up.

If you really want to manually close, here are a couple options:
Call mongo.close() after you call get_queue_info(queue).
Instead of just returning the data, save it to a var then close the connection and return the var.
EDIT:
upon looking it up, you don't need to manually close it.
You should take advantage of connection pooling, just create one MongoClient that lasts for the entire life of your process.
I think the reason your bot is executing commands pretty slowly is because MongoDB is taking so much CPU (review your schema or index design)

Thanks everyone. I guess I don't need to close the connection!

Related

Firestore "Stream Removed" Error After 3 Minutes Doing Nothing

I'm working on .NET Windows Form App which uses Google Cloud Firestore as Database. I've created functions (using Google.Cloud.Firestore NuGet Package functions) to read/write database documents. Everything working greatly but if app doesn't use any of this read/write functions more than 2-3 minutes, i'm getting this error: Grpc.Core.RpcException: 'Status(StatusCode="Unknown", Detail="Stream removed" But if uses read/write functions every 1-2 minutes, i do not get this error in short period. I can create a thread function to keep my database connection active but it causes unnecessary reads or writes. How can i solve it?
To Reproduce Error
string Path = AppDomain.CurrentDomain.BaseDirectory + #"AdminSDKName.json";
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", Path);
FirestoreDb DataBase = FirestoreDb.Create("DatabaseID");
Query QRef = DataBase.Collection("CollectionID").Document("DocID").Collection("CollectionID").WhereEqualTo("isTrue", false);
QuerySnapshot snap = await QRef.GetSnapshotAsync();
Console.WriteLine(snap.Count.ToString());
Console.WriteLine("Waiting for 5 minutes..");
Task.Delay(300000).Wait();
Console.WriteLine("Waited for 5 minutes");
snap = await QRef.GetSnapshotAsync();
Console.WriteLine(snap.Count.ToString());
Console.WriteLine("Done without any error.");
I get error after "Waited for 5 minutes" line.
Update
If i connect my computer network to mobile phone network i do not get any error.
I have a feeling you're seeing a part of Firestore's connection management here. If that's indeed what we're seeing, the connection should be reestablished when needed and there's nothing you can change about this through the API.
A solution would be to find out what is closing the stream prematurely. The configuration of Grpc.Core to send a keepalive packet once a minute can be found in the Github.
I suggest you try the code on a few different networks if you can, keeping everything else the same, to see if you can identify what is closing the connection.
Please refer to the User guide.
If this does not resolve, update your question with minimal reproducible code.

Moving from file-based tracing session to real time session

I need to log trace events during boot so I configure an AutoLogger with all the required providers. But when my service/process starts I want to switch to real-time mode so that the file doesn't explode.
I'm using TraceEvent and I can't figure out how to do this move correctly and atomically.
The first thing I tried:
const int timeToWait = 5000;
using (var tes = new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl") { StopOnDispose = false })
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
using (var tes = new TraceEventSession("TEMPSESSIONNAME", TraceEventSessionOptions.Attach))
{
Thread.Sleep(timeToWait);
tes.SetFileName(null);
Thread.Sleep(timeToWait);
Console.WriteLine("Done");
}
Here I wanted to make that I can transfer the session to real-time mode. But instead, the file I got contained events from a 15s period instead of just 10s.
The same happens if I use new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl", TraceEventSessionOptions.Create) instead.
It seems that the following will cause the file to stop being written to:
using (var tes = new TraceEventSession("TEMPSESSIONNAME"))
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
But here I must reenable all the providers and according to the documentation "if the session already existed it is closed and reopened (thus orphans are cleaned up on next use)". I don't understand the last part about orphans. Obviously some events might occur in the time between closing, opening and subscribing on the events. Does this mean I will lose these events or will I get the later?
I also found the following in the documentation of the library:
In real time mode, events are buffered and there is at least a second or so delay (typically 3 sec) between the firing of the event and the reception by the session (to allow events to be delivered in efficient clumps of many events)
Does this make the above code alright (well, unless the improbable happens and for some reason my thread is delayed for more than a second between creating the real-time session and starting processing the events)?
I could close the session and create a new different one but then I think I'd miss some events. Or I could open a new session and then close the file-based one but then I might get duplicate events.
I couldn't find online any examples of moving from a file-based trace to a real-time trace.
I managed to contact the author of TraceEvent and this is the answer I got:
Re the exception of the 'auto-closing and restarting' feature, it is really questions about the OS (TraceEvent simply calls the underlying OS API). Just FYI, the deal about orphans is that it is EASY for your process to exit but leave a session going. This MAY be what you want, but often it is not, and so to make the common case 'just work' if you do Create (which is the default), it will close a session if it already existed (since you asked for a new one).
Experimentation of course is the touchstone of 'truth' but I would frankly expecting unusual combinations to just work is generally NOT true.
My recommendation is to keep it simple. You need to open a new session and close the original one. Yes, you will end up with duplicates, but you CAN filter them out (after all they are IDENTICAL timestamps).
The other possibility is use SetFileName in its intended way (from one file to another). This certainly solves your problem of file size growth, and often is a good way to deal with other scenarios (after all you can start up you processing and start deleting files even as new files are being generated).

Siemens S7-1200. TRCV_С. Error code: 893A; Event ID 02:253A

Please, help to solve the problem with communication establishment between PC and 1211C (6ES7-211-1BD30-0XB0 Firmware: V 2.0.2). I feel that I've made a stupid mistake somewhere, but can't figure out where exactly it is.
So, I'm using function TRCV_С...
The configuration seems to be okay:
When i set the CONT=1, the connection establishes without any problems...
But, when i set EN_R=1, I'm getting "error 893A".
That's what I have in my diagnostic buffer: (DB9 - is a block where the received data is supposed to be written)
There is an explanation given for "893A" in the manuals: Parameter contains the number of a DB that is not loaded. In diag. buffer its also written that DB9 is not loaded. But in my case it is loaded! So what should I do in this case?
it seems that DB were created or edited manually due to which they are miss aligned with FB instances try removing and DB and FB instances and then add again instances of FBs with automatically created DBs and do a offline dowonload

Quickly Testing Database Connectivity within the Entity Framework

[I am new to ADO.NET and the Entity Framework, so forgive me if this questions seems odd.]
In my WPF application a user can switch between different databases at run time. When they do this I want to be able to do a quick check that the database is still available. What I have easily available is the ObjectContext. The test I am preforming is getting the count on the total records of a very small table and if it returns results then it passed, if I get an exception then it fails. I don't like this test, it seemed the easiest to do with the ObjectContext.
I have tried setting the connection timeout it in the connection string and on the ObjectConntext and either seem to change anything for the first scenario, while the second one is already fast so it isn't noticeable if it changes anything.
Scenario One
If the connect was down when before first access it takes about 30 seconds before it gives me the exception that the underlying provider failed.
Scenario Two
If the database was up when I started the application and I access it, and then the connect drops while using the test is quick and returns almost instantly.
I want the first scenario described to be as quick as the second one.
Please let me know how best to resolve this, and if there is a better way to test the connectivity to a DB quickly please advise.
There really is no easy or quick way to resolve this. The ConnectionTimeout value is getting ignored with the Entity Framework. The solution I used is creating a method that checks if a context is valid by passing in the location you which to validate and then it getting the count from a known very small table. If this throws an exception the context is not valid otherwise it is. Here is some sample code showing this.
public bool IsContextValid(SomeDbLocation location)
{
bool isValid = false;
try
{
context = GetContext(location);
context.SomeSmallTable.Count();
isValid = true;
}
catch
{
isValid = false;
}
return isValid;
}
You may need to use context.Database.Connection.Open()

SQLConnection Pooling - Handling InvalidOperationExceptions

I am designing a Highly Concurrent CCR Application in which it is imperative that I DO NOT Block or Send to sleep a Thread.
I am hitting SQLConnection Pool issues - Specifically getting InvalidOperationExceptions when trying to call SqlConnection.Open
I can potentially retry a hand full of times, but this isn't really solving the problem.
The ideal solution for me would be a method of periodically re-checking the connection for availablity that doesn't require a thread being tied up
Any ideas?
[Update]
Here is a related problem/solution posted at another forum
The solution requires a manually managed connection pool. I'd rather have a solution which is more dynamic i.e. kicks in when needed
Harry, I've run into this as well, also whilst using the CCR. My experience was that having completely decoupled my dispatcher threads from blocking on any I/O, I could consume and process work items much faster than the SqlConnection pool could cope with. Once the maximum-pool-limit was hit, I ran into the sort of errors you are seeing.
The simplest solution is to pre-allocate a number of non-pooled asynchronous SqlConnection objects and post them to some central Port<SqlConnection> object. Then whenever you need to execute a command, do so within an iterator with something like this:
public IEnumerator<ITask> Execute(SqlCommand someCmd)
{
// Assume that 'connPort' has been posted with some open
// connection objects.
try
{
// Wait for a connection to become available and assign
// it to the command.
yield return connPort.Receive(item => someCmd.Connection = item);
// Wait for the async command to complete.
var iarPort = new Port<IAsyncResult>();
var iar = someCmd.BeginExecuteNonQuery(iarPort.Post, null);
yield return iarPort.Receive();
// Process the response.
var rc = someCmd.EndExecuteNonQuery(iar);
// ...
}
finally
{
// Put the connection back in the 'connPort' pool
// when we're done.
if (someCmd.Connection != null)
connPort.Post(someCmd.Connection);
}
}
The nice thing about using the Ccr is that it is trivial to add the following the features to this basic piece of code.
Timeout - just make the initial receive (for an available connection), a 'Choice' with a timeout port.
Adjust the pool size dynamically. To increase the size of the pool, just post a new open SqlConnection to 'connPort'. To decrease the size of the pool, yield a receive on the connPort, and then close the received connection and throw it away.
Yes, connections are kept open and out of the connection pool. In the above example, the port is the pool.