I have a case where on a pretty regular select the call to SqlDataReader.Close() takes 10+ seconds to return. The only thing unusual is the select returns 20 rows but in this case none of the rows are read.
DbDataReader reader = (DbDataReader) cmd.ExecuteReader(CommandBehavior.Default);
reader.MoveNext();
var row = de.Current;
// lots of other code that does not touch this.
reader.Close();
Why does it take so long? And more important, what can I do to make it fast?
I couldn't find out what/why this is occurring. So on the call to close my object, I create a worker thread and have that close the data reader and connection. I then return immediately so the user sees no delay. Works fine.
Update: As per SqlDataReader.Close() it can be reduced by calling the Cancel method of the associated SqlCommand object before calling the Close method. h/t Lingaraj Mishra
Related
I am using a gen_server behaviour and trying to understand how can handle_info/2 be triggered from a timeout occurring in a handle_call for example:
-module(server).
-export([init/1,handle_call/3,handle_info/2,terminate/2).
-export([start/0,stop/0]).
init(Data)->
{ok,33}.
start()->
gen_server:start_link(?MODULE,?MODULE,[]).
stop(Pid)->
gen_server:stop(Pid).
handle_call(Request,From,State)->
Return={reply,State,State,5000},
Return.
handle_info(Request,State)->
{stop,Reason,State}.
terminate(Reason,State)->
{ok,S}=file:file_open("D:/Erlang/Supervisor/err.txt",[read,write]),
io:format(S,"~s~n",[Reason]),
ok.
What i want to do:
I was expecting that if I launch the server and would not use gen_server:call/2 for 5 seconds (in my case) then handle_info would be called, which would in turn issue the stop thus calling terminate.
I see it does not happen this way, in fact handle_info is not called at all.
In examples such as this i see the timeout is set in the return of init/1.What I can deduce is that it handle_info gets triggered only if I initialize the server and issue nothing (nor cast nor call for N seconds).If so why I can provide Timeout in the return of both handle_cast/2 and handle_call/3 ?
Update:
I was trying to get the following functionality:
If no call is issued in X seconds trigger handle_info/2
If no cast is issued in Y seconds trigger handle_info/2
I thought this timeouts can be set in the return of handle_call and handle_cast:
{reply,Reply,State,X} //for call
{noreply,State,Y} //for cast
If not, when are those timeouts triggered since they are returns?
To initiate timeout handling from gen_server:handle_call/3 callback, this callback has to be called in the first place. Your Return={reply,State,State,5000}, is not executed at all.
Instead, if you want to “launch the server and would not use gen_server:call/2 for 5 seconds then handle_info/2 would be called”, you might return {ok,State,Timeout} tuple from gen_server:init/1 callback.
init(Data)->
{ok,33,5000}.
You cannot set the different timeouts for different calls and casts. As stated by Alexey Romanov in comments,
Having different timeouts for different types of messages just isn’t something any gen_* behavior does and would have to be simulated by maintaining them inside state.
If one returns {reply,State,Timeout} tuple from any handle_call/3/handle_cast/2, the timeout will be triggered if the mailbox of this process is empty after Timeout.
i suggest you read source code:gen_server.erl
% gen_server.erl
% line 400
loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
it helps you to understand the parameter Timeout
I was trying to assign timestamp and watermarks to a stream by implementing the AssignerWithPeriodicWatermarks, inside the function, it implements:
override def getCurrentWatermark: Watermark = {
// this guarantees that the watermark never goes backwards.
val potentialWM = currentMaxTimestamp - maxOutOfOrderness
if (potentialWM >= lastEmittedWatermark) lastEmittedWatermark = potentialWM
new Watermark(lastEmittedWatermark)
}
override def extractTimestamp(element: T, previousElementTimestamp: Long): Long = {
val timestamp = element.streamTime // something exists in the stream
if (timestamp > currentMaxTimestamp) currentMaxTimestamp = timestamp
timestamp
}
However, I still got watermarks of the default value -9223372036854775808, and when I tried to add printing inside both functions, I found only println inside extractTimestamp was printed, which is saying function of getCurrentWatermark was never called.
The implementations seem to be right, because the same code was able to run on another script(some code not written by me).
PS: It's not the first time that I encountered negative watermark, what I found is that after a certain period of time, the watermark will go positive, however I am still quite confused what happened at the beginning.
The issue is that You are using AssignerWithPeriodicWatermark which does not generate watermarks per event but in intervals. Whenever You are using AssingerWithPeriodicWatermark You should set call the setTheAutowatermarkInterval on the execution environment. The value that You provide there will be the interval that the getCurrentWatermark will be called with.
If You haven't set it then the method will never be called, thus You will never have a watermark changed.
For testing and learning, You can consider using AssignerWithPunctuatedWatermark as this will simply emit watermark for each event.
EDIT:
As it was mentioned below this answer, the default value for autowatermarkInterval is actually 200 ms. Also, using the AssignerWithPunctuatedWatermark doesn't mean You need to emit the Watermark for each event, but the method for emitting them will be called for each event. If You don't want to emit the Watermark then the method should simply return null.
Guys help me to understand the timeouts usage. The documentation gives quite a couple of words about them:
popTimeout- Retrieves the previous timeout value from a stack, restores it as the current timeout value, and returns it.
pushTimeout - Stores the current timeout value on a stack and sets a new timeout value.
They also provide some code:
target = UIATarget.localTarget();
target.pushTimeout(2);
// attempt element access
target.popTimeout();
But I don't exactly understand how and when to use them. Can anybode give an example?
During automation testing, some elements might not become visible right away. so instruments uses a timeout (default 5 seconds) to wait for requested elements. They call this the grace period.
Sometimes the default grace period might not be what you need, so you can change the timeout to a shorter or longer value.
Using the pushTimeout and popTimeout makes sure that the previous grace period is restored after calling popTimeout, without the need to remember the previous grace period.
For example: in one of my tests, I don't want to wait for a popover to become active, but I just want to know if there is a popover active, and dismiss it if there is:
target.pushTimeout(0.0);
if ( target.isDeviceiPad() && ! isNull( popOver= app.mainWindow().popover() ) )
{
UIALogger.logDebug(" dismiss popup by tapping somewhere");
popOver.dismiss();
target.delay(0.2);
}
target.popTimeout();
BTW, the isNull() is a custom function I made, but you probably understand what is going on.
I have 20 different methods and use datareader to read and get result from these functions in the same event.In top of page I create datareader and then begin to load it step by step(It uses same connection and same data access function).Till 15.function datareader loads without problem but after 15,it loads slowly(record count is about 20-30).When i close datareader after 15.function,this problem doesnt occur.But now after 15.function,i should close datareader if i execute some function.Why does this problem occur,I dont know.I posted sample code here.
'Trying method 1
strSQL.ToString="Select * from A"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
'Trying method 2
strSQL.ToString="Select * from B"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
'Trying method 15
strSQL.ToString="Select * from K"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
AFTER 15. EXECUTION,DATAREADER BEGINS TO LOAD DATA SLOWLY.WHEN I ADD DR.CLOSE AND EXECUTE IT,I DONT HAVE PROBLEM.IF I DONT DO IT,IT LOADS 20 RECORDS WITHING 5 SECONDS.THIS IS MY READANDBIND FUNCTION.I AM CONNECTING ORACLE 11 G.WHAT CAN CAUSE THIS PROBLEM?
Public Shared Function ReadAndBind(ByVal SQL As String) As OracleDataReader
Dim oraCommand As New OracleCommand
With oraCommand
.Connection =
New OracleConnection(CONN_NAME)
.CommandText = SQL
Dim dtreader As OracleDataReader
Try
.Connection.Open()
dtreader = .ExecuteReader(CommandBehavior.CloseConnection)
Catch ex As Exception
Exception_Save(ex.Message, oraCommand.ToString)
Throw
Finally
'.Connection.Close()
'.Connection.Dispose()
oraCommand.Dispose()
oraCommand =
Nothing
End Try
Return dtreader
End With
End Function
No, you are not using the same connection for all the commands, you are opening a new connection for each one. As you fail to close them, at the end of the code you will be having 20 database connections open at once.
Also, you are not using a single data reader, you are creating a new data reader for each query. When you assign the method result to the dr variable it's not reusing the data reader, it's throwing away the reference to one reader and replaces it with a new one. It's normal to use one reader for each result, but it means that you have to close each data reader before getting the next, or you will get an unreachable object that holds on to a database connection until the garbage collector removes it.
If you close each reader before getting the next, the database connection will be closed and returned to the connection pool so that it can be reused for the next query. Slightly better would be to create a single connection object for the page and use that for each command, that will save a few round trips to the database.
I am Using WaitforComplete() in watiN but it doesnt seems to work well. As it executes the next statement even if you have given longer time to wait. I am using thread.sleep() to stop my application until it gets the desired page or element. But the thing is pages are so much dynamic that sometimes it takes much longer time as specified.
Any better solution. Any thing that will catch the page return dynamically and dont go to execute next statments in application.
Sample of Code
'Show Details page
Assert.AreEqual("Confirmation", _internetExplorer.Title)
If (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists) Then
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click()
Else
Assert.Fail("Could not Find Finish Booking Button on Confirmation Page")
End If
System.Threading.Thread.Sleep(100000)
'Show Booking Summary page
Assert.AreEqual("Display Booking", _internetExplorer.Title)
I want something that detect the return of page dynamically. instead of giving some constant value.
WaitForComplete only works well if there is a postback after some action. Otherwise you have to find something else to wait for. Following an example on how to wait for the specified title:
_internetExplorer.Element("title", "Confirmation").WaitUntilExists();
I would always prefer to use one of the WaitXXX methods instead of Thread.Sleep cause the WaitXXX methods do only wait until the contraint is met. Where as Sleep waits for the time you specified. If its to long, time is waisted. If its to short, problems arise.
HTH,
Jeroen
The WaitForComplete method esentially moves on once the browser has set it's readystate to comllete and the busy state to false.
What I typically do is to try and access what you need to, then perform a thread.sleep for say half a second, then try again. I also have a global timeout that quits after say 10 seconds.
int timeout = 20;
bool controlFound = false;
for (int i = 0; i < timeout; i++)
{
if (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists)
{
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click();
controlFound = true;
break;
}
else
{
System.Threading.Thread.Sleep(500);
}
}
if (!controlFound)
{
Assert.Fail("Control not found");
}
If it is executing the next statement, it should be finding the corresponding element. I suggest posting a sample of the code you are trying.