Pyodbc - Web.py blocking connection - pyodbc

I am currently using PYODBC in Web.py to connect to a SQL Azure DB and so far all was well. We recently added a new call into our Web.py URL list which made a cursor call like follows
class get_teas:
def GET(self):
con = pyodbc.connect(con_string,timeout=120)
con.timeout = 120
cur = con.cursor()
for row in cur.execute("{CALL get_all_tea_in_china ("+user_data.theother+",'"+user_data.this+"','"+user_data.that+"')}"):
...do some dictionary stuff
cur.commit();
cur.close()
return 'DONE'
However we have recently noticed due to get_all_tea_in_china being a long call that it is blocking all subsequent calls within web.py which is not great for hopefully obvious reasons! Is there a way of making it such that this call is not blocking?
If anyone can help I would really appreciate it.

You can use celery,put your long call in a asynchronous task queue.http://www.celeryproject.org/

Related

How do you get code to execute at the end of a procedure?

I'm working on a new piece of code at work to assist the rest of the programmers in making app server calls. Previously we just had a .i file and relied on the developer to make sure you made all the right calls and cleaned up the app server connection at the end of the program. Obviously some people have forgotten to do that in the past and it's caused problems for us.
I've been building a basic appserver.cls file, but I can't figure out how to get it to disconnect at the end of the program.
I've tried the following things so far.
ON CLOSE OF THIS-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't seem to fire at the end of the webspeed call.
DESTRUCTOR appserver():
cleanupAppServer().
END DESTRUCTOR.
This works when it does garbage collection, but Progress doesn't seem to do garbage collection at the end of a webspeed call and the objects are still in memory (which is an entirely different issue that I need to deal with).
ON CLOSE OF SESSION:LAST-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't even compile obviously.
I've tried a whole bunch of other things that are variants on these three to no avail.
Is there any way to do what I'm asking? Bonus points if it can be inside the appserver.cls file.
If I understand the question, you want to disconnect from another AppServer once the work is done. Would try something along the lines of the below work?
Create a AppServer-handle-wrapper class. This class is responsible for the A/S connection; it has a public "Handle" (or similarly-named) property that you can use to run stuff on the AppServer.
In this class' destructor you can add code that does your clean-up : disconnect and delete server handle .
Code that wants to run something on the AppServer does something like ...
def var asConn as AppServerConnection.
asConn = new AppServerConnection().
run foo.p on asConn:Handle (param1, out param2).
// cause GC
asConn = ?.
// manually destroy
delete object asConn.
The destructor will then do the right thing.
Note that if you have this code in an internal procedure or method, then the variable would go out of scope at the end of it, and the GC would kick in.
There's an example of this approach at https://github.com/consultingwerk/ADE-Sourcecode/blob/566ac0a6e085d6305a8f364f13a1d805d3597d2a/src/netlib/OpenEdge/Net/ServerConnection/ClientSocket.cls
Bear in mind that in the ClientSocket is that the handle is private - you may want to make it public for a general AppServer connection.

How does R handle closing of data base connections

If I create a data base connection within a function, the connection objects gets destroyed when the function finished executing. Does this reliably close the data base connection, or would it better to to close it manually first?
Why I need to know this:
I am working on a package that creates data base connections on the fly with either RODBC or RJDBC as backend. I designed my function interfaces so that you can pass in either username and password, or a connection object. Usually, when I pass in a connection object I do not want the connection to be closed on the termination of the function, while when I pass in username and password I want it to be closed.
If I do not have to worry about open connections, it would simplify things a lot for me and also save me a lot of headaches.
Answer & More:
I markded Benjamin's answer as the answer since it gives good advice, though actually what I was looking for is more Marek's comment that (paraphrased:) connections can be open after the connection object is destroyed and there is no way to access them from R any more.
I ended up going for a solution that involves creating an R6 class and defining finalize() method that closes the connection (it's a more powerful than on.exit()), but that is beyond the scope of this Question.
I write a lot of functions that create ODBC connections when they are called. My standard practice is:
conn <- RODBC::odbcDriverConnect(...)
on.exit(RODBC::odbcClose(conn))
By putting the creation of the object and the code for its closing next to each other, I know that the connection will be closed when the function is finished. Using on.exit has the added advantage of closing the connection even if the function stops on an error.
Edit:
In the problem as your edit has described it, I think the same pattern is relevant. You need to declare on.exit in a manner that it only gets called if you don't provide the connection object.
db_function <- function(conn = NULL, uid, pwd){
if (is.null(conn)){
conn <- RODBC::odbcDriverConnect(...) # Build conn with uid and pwd
on.exit(RODBC::odbcClose(conn))
}
}
A trivial example to show by-passing on.exit
test_fun <- function(on_exit = FALSE){
if (on_exit) on.exit(print("hello world"))
"Look at me"
}
test_fun()
test_fun(TRUE)

LogicApps Web API making it Asynchronous

I had to write a Web API to insert data into custom on-premise DB and then call a stored procedure for LogicApps to use. The LogicApps' call timeouts when passing large amopnts of data. So I'm trying to use this solution I found here:
LogicAppsAsyncResponseSample
So I would basically put all my code into the doWork like this:
foreach (var record in records)
{
...
//Insert record
cmd.ExecuteNonQuery();
}
...
//Call SP
cmd.ExecuteNonQuery();
runningTasks[id] = true;
My question is should I make my code in doWork, asynchronous? Use Await as needed and ExecuteNonQueryAsync instead of ExecuteNonQuery and add AsynchronousProcessing to my connection string?
Alternatively, too I was actually considering writing this to be "Fire and Forget". Meaning I would start a thread in my API to call doWork as in the sample and return OK instead of Accepted right away. Then I wouldn't need to store thread statuses or have the chekcStatus method. This is OK for me since the API can send alerts if anything fails. The only advantage to the noted sample is I can eventually return something to LogicApps indicating success or not and show it in my LogicApps' log (one place to see all). Is "Fire and Forget" a sound practice?
FYI: the call to dowork in the sample is:
new Thread(() => doWork(id)).Start();

Connect to SQLite database in Slick doesn't work but doesn't throw an error

So the documentation for Typesafe's Slick is very thin and its examples are for Play which doesn't help very much working in Eclipse.
I try to connect to an existing SQLite database on my system, which consists of one table "Maintenance_Request".
import slick.driver.SQLiteDriver.api._
import scala.concurrent.ExecutionContext.Implicits.global
object starter {
def main(args: Array[String]): Unit = {
val db = Database.forURL("jdbc:sqlite:/home/sq/workspace/dbFun/IOdb.db", driver = "org.sqlite.JDBC")
val action = sql"select CATEGORY from MAINTENANCE_REQUEST".as[(Int)]
db.run(action).foreach(println)
}
}
Starting the program doesn't give me any result though. Also if i change the path, like leaving out a character, so it is not a valid path, doesn't throw an error! So i don't have a clue what is working and what is not working.
Is there a way of knowing , if variable db is connected to a database?
Any way of knowing that Database.forURL worked or failed??
I suspect the reason you see no result is just that your main program is completing before the query has completed.
What I mean is, the type of db.run(action) will be Future[Seq[Int]]. Calling foreach on that does not block for a result. The behaviour of foreach on a Future is noted here:
It is important to note that calling the foreach combinator does not block to traverse the value once it becomes available. Instead, the function for the foreach gets asynchronously executed only if the future is completed successfully.
-- http://docs.scala-lang.org/overviews/core/futures.html
So what you can do is await the result:
import scala.concurrent.Await
import scala.concurrent.duration._
val result = Await.result(db.run(action), 2 seconds)
result.foreach(println)
...which will ensure you see the result printed before your program terminates.
In terms of errors connecting to a database...
in forUrl, if the connection string is not a valid recognized scheme, you'll see an exception such as java.sql.SQLException: No suitable driver
if you give a valid URL, but the wrong database name, that is going to depend on the database in question. For H2, and I suspect SQLite, you'll probably create a new empty database. There may be parameters you can pass in the JDBC URL to control this behaviour, but that will be driver/database specific.

Asp.Net MVC double submit/request breaks SQL connection

I am running into a strange problem I don't fully understand. The main symptom is that when I double click a link (that points to a controller action) in my MVC application, my database server connection gets blown, and I get the error :
Execution of the command requires an open and available connection. The connection's current state is broken.
If I step through starting at a breakpoint at the top of the controller action, it will step down a couple lines and then jump back up to the breakpoint. Somehow the first request isn't executing fully before the second one gets there, and somehow my database connection breaks when it gets to any query. Every time this happens, I have to restart the application server.
It was happening intermittently at first, but the double clicking of links seems to reproduce it everytime. Does this happen to anyone else? What am I missing here?
Thanks,
rusty
Update :
A.) I incorrectly tagged this as Linq-to-sql when we are actually using Linq-to-entities.
B.) The connection object is defined as a member variable of the controller :
namespace C2S.Controllers
{
public class ArtifactController : Controller
{
private c2sEntities _entities = new c2sEntities();
...
I noticed in some of the asp.net tutorials they declare the variable in the same spot but have a separate constructor for the controller where the db object is initialized. Does this make any difference?
C.) The problem is not only with the double-clicking as described above. The connection breaks at other seemingly random times; I cannot seem to reproduce the error consistently (even double-clicking does not always break it). Restarting the web site usually fixes it, although sometimes I have to restart the host machine. After its back up, repeating the same sequence of actions usually does not reproduce the same error!
Maybe there's something I don't understand about setting up my linq-to-entities classes or the nature of the database connection. Does anyone have any thoughts? I really don't even know how to investigate this one!
Thanks again
Rusty
It's a bit difficult to say from your description of the problem, but a first guess would be:
Is your connection object static (i.e. controller or application level) or defined locally within the action? Double clicking a link would fire the event twice and that sounds like what you are describing here. So the first call creates the connection, then the 2nd call comes in and tramps all over the 1st call to the method, breaking the connection it thinks it has.
Edit: Does the problem only occur on double clicks. Does it work as expected if you only single click on the link? An example of the code in question would help.
I am guessing that you're not properly closing your database connection. You should consider making use of the using statement.
using(SqlConnection conn = new SqlConnection("connstring")) {
using (SqlCommand cmd = new SqlCommand("SQLSTATEMENT", conn)) {
// more code here......
}
}
This will ensure that your connection is closed even if there's an error in your code somewhere.
Read all about it here: http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx

Resources