Qt (QFtp) question - c++

Hello i am learning qt and trying to upload a file using QFtp i wrote the folowing code
this->connect(this->ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));
this->connect(this->ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(dataTransferProgress(qint64, qint64)));
this->connect(this->ftp, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));
.....
if(this->file.open(QIODevice::ReadWrite))
{
this->ftp->setTransferMode(QFtp::Active);
this->ftp->connectToHost(this->settings->getHost());
this->ftp->login(this->settings->getUser(), this->settings->getPassword());
this->ftp->cd(remoteFilePath);
this->ftp->get(this->fileName, &this->file);
this->ftp->close();
}
and it kind of stops it reports in dataTransferProgress that it is at 0/XXX but the slot is never invoked again (using the same code but with the get function i can download a file and it works without a problem) also the error that i get after the time out is QFtp::UnknownError.

Assuming all the commands until get are successful, it's likely that you are closing the connection before get finishes. You should save the identifier returned by get and call close when the commandFinished signal is called with that identifier.
Note: Except setTransferMode all of the methods you used are asynchronous. They will be executed in the order that they are called, but since you aren't performing any error checking, it's possible for one to fail and the rest will still be attempted which might result in some confusion.
The proper way of doing this is to connectToHost first, if that's successful (you can track this with the commandFinished signal) call login etc.

Related

Correct way to stop asynchronous ISearchJob

I am going to use WUA API and begin execution of an asynchronous search for updates in this way:
CComPtr<SearchCallbackImpl> iscc_; <<-- Note you need to CreateInstance
CComPtr<ISearchJob> pUpJob_;
pUpJob_ = NULL;
pUpSearcher_->BeginSearch(
CComVariant(criteria.c_str()).bstrVal,
iscc_,
CComVariant(L"Scanning"),
&pUpJob_);
When I need to stop my program, but ISearchJob has not completed yet, I use this code:
if (pUpJob_)
{
CComVariant isStopped;
pUpJob_->get_IsCompleted(&isStopped.boolVal);
if (isStopped.boolVal == VARIANT_FALSE)
{
if (SUCCEEDED(pUpJob_->RequestAbort()))
{
pUpJob_->CleanUp();
pUpJob_.Release();
}
}
}
Generally this code works but sometime it hangs on pUpJob_->CleanUp(); and I do not have ability to stop my programm correctly.
So my questions are:
What is the correct way to stop asynchronous search job for updates?
Also i misunderstood what is difference between ISearchJob::CleanUp and ISearchJob::RequestAbort and how to use this methods to stop asynchronous search correctly?
Should this methods be used together or separately?
RequestAbort() is also asynchronous (the hint to that is in the name). After calling it, you should call pUpSearcher_->EndSearch(); it will return an ISearchResult with ResultCode equal to orcAborted if the abort was successful. Then you can free your resources.
I'm not fully sure how CleanUp() is supposed to be used, but this page seems to imply it's intended for scripts that have callbacks, and that you're not supposed to call CleanUp() from within a callback. Not sure where your code for cancelling is run.

Ember.js - Function finished before store is done

I'm building an ember app, and I keep running into the same problem where I make a call to the store, but the function keeps compiling before the store has retrieved the data from the backend. Specifically I'm having the problem with a findRecord. I've implemented it both ways:
var admin = this.store.findRecord('admin', 1);
console.log(admin.get('season'));
console.log('Are we here?');
and
this.store.findRecord('admin', 1).then(function(admin) {
console.log(admin.get('season'));
});
console.log('Are we here?');
In both cases, the Are we here? is logged BEFORE the season. Obviously the console logs are just for the example, and it creates an actual problem with what I'm trying to get done. Does anybody know a simple fix for this delay?
Thanks.
Of course it is. It's an asynchronous behavior. It takes some time to solve promise which is returned from findRecord(), thus the consequence is:
this.store.findRecord(); //synchronous
console.log('we are here'); //synchronous
in the meantime a promise returned from findRecord() gets resolved (asynchronous behavior)
console.log(admin.get('season'));
An asynchronous call will not stop your code from progressing, that´s the purpose of it. Else it would block UI updates and user interaction while loading data.

Rails - run pusher in background

I use Pusher in my Rails-4 application.
The problem is that sometimes the connection is slow, so the execution of the code becomes slower.
I also get from time to time the following error:
Pusher::HTTPError: execution expired (HTTPClient::ConnectTimeoutError)
I send signals via Pusher with this code:
Pusher[channel].trigger!(event, msg)
I would like to execute it in background, so if an exception is thrown it will not break the flow of my app, and neither slow it down.
I tried to wrap the call with begin ... rescue but it didn't solve the exception problem. Of course even if it would, it wouldn't solve the slow-down problem i want to avoid.
Information on performing asynchronous triggers can be found here:
https://github.com/pusher/pusher-gem#asynchronous-requests
This also provides you within information on catching/handling errors.
Finally I implemented this solution:
Thread.new do
begin
Pusher[channel].trigger!(ch, ev, msg)
ActiveRecord::Base.connection.close
rescue Pusher::Error => e
Rails.logger.error "Pusher error: #{e.message}"
end
end

Using QFtp, abort list() command

I am actually wanting to get the newest files from a ftp server. For this, I am currently using QFtp to access the server and retrieve what I need.
This is what I do (like every 3 minutes) :
Connection & authentification to the server.
list() command to list all the files.
for each file listed by the list() command I call a slot that verify if the file currently listed has not been already downloaded (I am relying on the date of the file). If the file is recent enough, I download it.
So, it works. But it it really slow because there are thousands of files on the server and each time I verify the date of each of them. Is it possible to abort the list() command for example when I find a file too old ? Or is there another smarter way to fasten the process ?
Yes, there is a way to abort the long-playing command. When you call QFtp::list() it starts execution command on Ftp server, and if command finds an entry, QFtp emits QFtp::listInfo(const QUrlInfo &) signal. You can handle that signal, and check, whether the QUrlInfo::lastModified() returned time is too old. If yes, you can call QFtp::abort() function to abort the list command's execution on the server. Here is the sample code:
Establish connection to handle the ftp signals
connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),
this, SLOT(onNewEntry(const QUrlInfo &)));
Implementation of the listInfo signal handling slot:
void MyFtp::onNewEntry(const QUrlInfo &url)
{
// If url.lastModified() is less than some time
// ftp->abort();
}

storagefile::ReadAsync exception in c++/cx?

I have been trying to use c++/cx StorageFile::ReadAsync() to read a file in a store-apps, but it always return an invalid params exception no matter what
// "file" are returned from FileOpenPicker
IRandomAccessStream^ reader = create_task(file->OpenAsync(FileAccessMode::Read)).get();
if (reader->CanRead)
{
BitmapImage^ b = ref new BitmapImage();
const int count = 1000000;
Streams::Buffer^ bb = ref new Streams::Buffer(count);
create_task(reader->ReadAsync(bb, 1, Streams::InputStreamOptions::None)).get();
}
I have turn on all the manifest capabilities and added "file open picker" + "file type association" for Declarations. Any ideas ? thanks!
ps: most solutions I found is for C#, but the code structure are similar...
If this code is executing on the UI thread (or in any other Single Threaded Apartment, or STA), then the calls to .get() will throw if the tasks have not yet completed, because the call to .get() would block the thread. You must not block the UI thread or any other STA, and when compiling with C++/CX support enabled, the libraries enforce this.
If you turn on first chance exception handling in the debugger (Debug -> Exceptions..., check the C++ Exceptions check box), you should see that the first exception to be thrown is an invalid_operation exception, from the following line in <ppltasks.h>:
// In order to prevent Windows Runtime STA threads from blocking the UI, calling
// task.wait() task.get() is illegal if task has not been completed.
if (!_IsCompleted() && !_IsCanceled())
{
throw invalid_operation("Illegal to wait on a task in a Windows Runtime STA");
}
The "invalid parameter" you are reporting is the fatal error that is caused when this exception reaches the ABI boundary: the debugger is notified that the application is about to terminate because this exception was unhandled.
You need to restructure your code to use continuations, using task::then, as described in the article Asynchronous Programming in C++ Using PPL
Just to make sure you understand the async pattern, what is happening in your code is that you call create_task and immediately after that task has started you are trying to get the result with .get(). Calls to .get() will throw immediately if the task is still running or the file could not be found. Therefore, the correct way of structuring this is using a .then on your file task, ensuring that you have the result of this task before starting the next one.
create_task(file->OpenAsync(FileAccessMode::Read)).then([](IRandomAccessStream^ reader)
{
//do stuff with the reader
});
At that point the reader is available so you can do whatever you want to, even start a new task.
Also, it is possible that the call to OpenAsync is failing cause the file is empty, I would add a try catch block to the previous task, the one that gets the file, just to make sure that's not the problem.