Opened 10 months ago

Closed 10 months ago

#13404 closed Patch - Bug Fix (fixed)

QT5: QFileInfo is not registered to QMetaType at startup anymore

Reported by: rcrdnalor Owned by: Bill Meek
Priority: minor Milestone: 29.2
Component: MythTV - Services API - Backend Version: v29-fixes
Severity: medium Keywords:
Cc: Ticket locked: no

Description

QT5: QFileInfo is not a registered QMetaType at startup anymore

When I use the Services API to retrieve a preview on a freshly booted backend, I get an empty xml file, if it is run straight after start of mythbackend:

wget -O preview.png http://<be-address>:6544/Content/GetPreviewImage?RecordedId=<n>

The preview.png looks like an xml file holding the xml body only:

$ cat ./preview.png
<?xml version="1.0" encoding="UTF-8"?><></>

The second attempt works as expected and returns a valid preview.png

Note: This causes missing icons or thumbnails in MythWeb:

Missing previews in MythWeb:

https://code.mythtv.org/trac/ticket/10707#comment:10
https://code.mythtv.org/trac/ticket/10707#comment:11

Missing Channel Icons in MythWeb:

https://lists.gt.net/mythtv/users/620286
https://forum.mythtv.org/viewtopic.php?f=6&t=2578&p=12580&hilit=icon#p12580  

Every mornig, when I fire up MythWeb, I get these missing thumbnails. MythWeb causes the httpworker of mythtv to spawn multiple threads at the same time, therefore, the first 5 or 6 previews are corrupt.

The reason for this is that in the file 'servicehost.cpp', the method 'QVariant MethodInfo::Invoke' tries to get the MetaType-index of 'QFileInfo' at line 81:

int nRetIdx = QMetaType::type( m_oMethod.typeName() );  

but QFileInfo is not registered to QMetaType at this time.

Note: After the first call, the type gets registered, because the Content Service 'QFileInfo Content::GetPreviewImage' is actually called.

Below the log excerpt with the applied path (01_add_logging_to_methodinfo_invoke.patch) for more verbosity. The log is done using the following loglevels: 'general:err,http:debug'

 I CoreContext httpserver.cpp:466 (HttpWorker) HttpWorker(9): New connection
 I HttpServer9 httprequest.cpp:1140 (GetParameters) sParams: 'RecordedId=10'
 I HttpServer9 httprequest.cpp:1332 (ParseRequest) (Request Header) accept: */*
 I HttpServer9 httprequest.cpp:1332 (ParseRequest) (Request Header) accept-encoding: identity
 I HttpServer9 httprequest.cpp:1332 (ParseRequest) (Request Header) connection: Keep-Alive
 I HttpServer9 httprequest.cpp:1332 (ParseRequest) (Request Header) host: A.B.C.D:6544
 I HttpServer9 httprequest.cpp:1332 (ParseRequest) (Request Header) user-agent: Wget/1.19.4 (linux-gnu)
 I HttpServer9 httprequest.cpp:1644 (ExtractMethodFromURL) ExtractMethodFromURL(end) : GetPreviewImage : /Content
 D HttpServer9 httpserver.cpp:376 (DelegateRequest) m_sBaseUrl: /Content
 I HttpServer9 servicehost.cpp:325 (ProcessRequest) ServiceHost::ProcessRequest: GetPreviewImage : GET /Content/GetPreviewImage?RecordedId=10 HTTP/1.1
 D HttpServer9 servicehost.cpp:85 (Invoke) MethodInfo::Invoke: nRetIndx is '0' and type is 'QFileInfo'.
 I HttpServer9 httprequest.cpp:369 (SendResponse) HTTPRequest::SendResponse(xml/html) () :200 OK -> W.X.Y.Z: 8
 D HttpServer9 httprequest.cpp:419 (SendResponse) Reponse Content Length: 44
 D HttpServer9 httprequest.cpp:450 (SendResponse) Response header size: 400 bytes
 W HttpServer9 httpserver.cpp:645 (run) HttpWorker(9): Error The remote host closed the connection (1)
 I HttpServer9 httpserver.cpp:693 (run) HttpWorker(9): Connection -1 closed. 1 requests were handled
 I CoreContext housekeeper.cpp:725 (Run) Queueing HouseKeeperTask 'DBCleanup'.
 I CoreContext housekeeper.cpp:725 (Run) Queueing HouseKeeperTask 'JobQueueRecover'.
 I CoreContext housekeeper.cpp:725 (Run) Queueing HouseKeeperTask 'LogClean'.
....
 I CoreContext httpserver.cpp:466 (HttpWorker) HttpWorker(58): New connection
 I HttpServer58 httprequest.cpp:1140 (GetParameters) sParams: 'RecordedId=10'
 I HttpServer58 httprequest.cpp:1332 (ParseRequest) (Request Header) accept: */*
 I HttpServer58 httprequest.cpp:1332 (ParseRequest) (Request Header) accept-encoding: identity
 I HttpServer58 httprequest.cpp:1332 (ParseRequest) (Request Header) connection: Keep-Alive
 I HttpServer58 httprequest.cpp:1332 (ParseRequest) (Request Header) host: A.B.C.D:6544
 I HttpServer58 httprequest.cpp:1332 (ParseRequest) (Request Header) user-agent: Wget/1.19.4 (linux-gnu)
 I HttpServer58 httprequest.cpp:1644 (ExtractMethodFromURL) ExtractMethodFromURL(end) : GetPreviewImage : /Content
 D HttpServer58 httpserver.cpp:376 (DelegateRequest) m_sBaseUrl: /Content
 I HttpServer58 servicehost.cpp:325 (ProcessRequest) ServiceHost::ProcessRequest: GetPreviewImage : GET /Content/GetPreviewImage?RecordedId=10 HTTP/1.1
 D HttpServer58 servicehost.cpp:85 (Invoke) MethodInfo::Invoke: nRetIndx is '1178' and type is 'QFileInfo'.
 I HttpServer58 httprequest.cpp:358 (SendResponse) HTTPRequest::SendResponse( File ) :200 OK -> W.X.Y.Z:
 I HttpServer58 httprequest.cpp:503 (SendResponseFile) SendResponseFile ( /mnt/data01/my_data01/recordings/3006_20180804082700.mkv.png )
 I HttpServer58 httprequest.cpp:1128 (TestMimeType) HTTPRequest::TestMimeType(/mnt/data01/my_data01/recordings/3006_20180804082700.mkv.png) - type is image/png
 D HttpServer58 httprequest.cpp:611 (SendResponseFile) Response header size: 471 bytes
 W HttpServer58 httpserver.cpp:645 (run) HttpWorker(58): Error The remote host closed the connection (1)
 I HttpServer58 httpserver.cpp:693 (run) HttpWorker(58): Connection -1 closed. 1 requests were handled

These stanzas indicate that something went wrong:

MethodInfo::Invoke: nRetIndx is '0' and type is 'QFileInfo'.
HTTPRequest::SendResponse(xml/html) () :200 OK -> W.X.Y.Z: 8"

Analysis:

Up to fixes/29, the 'QFileInfo' type was registered to 'QMetaType', but only for QT4:

See File 'libs/libmythservicecontracts/service.h' from branch fixes/29:

#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
Q_DECLARE_METATYPE( QFileInfo )
inline Service::Service(QObject *parent) : QObject(parent)
{
    qRegisterMetaType< QFileInfo >();
}
#else
inline Service::Service(QObject *parent) : QObject(parent) {}
#endif

This explains, that this bug is not visible in fixes/0.27 (QT4) and is a regression since v28 (QT5).

For QT5, it is not necessary anymore to declare the metatype, because this is already done in in the header file of <QFileInfo>, but registering 'QFileInfo' seems to be necessary for MythTV Services.

See attached patches 02_register_qfileinfo_at_startup_v29.patch and 02_register_qfileinfo_at_startup_v30_master.patch

The patch for master is compile time tested, only.

Enclosed the mythtv version (mythtv_version.txt).

Attachments (4)

01_add_logging_to_methodinfo_invoke.patch (1.2 KB) - added by rcrdnalor 10 months ago.
This patch adds additional log info to MethodInfo::Invoke.
02_register_qfileinfo_at_startup_v29.patch (669 bytes) - added by rcrdnalor 10 months ago.
Patch to register <QFileInfo> to QMetaType at startup for fixes/29
02_register_qfileinfo_at_startup_v30_master.patch (1.0 KB) - added by rcrdnalor 10 months ago.
Patch to register <QFileInfo> to QMetaType at startup for fixes/30 and master
mythtv_version.txt (1.0 KB) - added by rcrdnalor 10 months ago.
mythtv version information

Download all attachments as: .zip

Change History (11)

Changed 10 months ago by rcrdnalor

This patch adds additional log info to MethodInfo::Invoke.

Changed 10 months ago by rcrdnalor

Patch to register <QFileInfo> to QMetaType at startup for fixes/29

Changed 10 months ago by rcrdnalor

Patch to register <QFileInfo> to QMetaType at startup for fixes/30 and master

Changed 10 months ago by rcrdnalor

Attachment: mythtv_version.txt added

mythtv version information

comment:1 Changed 10 months ago by Bill Meek

Milestone: needs_triage30.1
Owner: set to Bill Meek
Status: newaccepted

comment:2 Changed 10 months ago by Gary Buhrmaster

FWIW, while I am not sure it is related (although the symptoms seem to be the same), and I have not done the research that the OP did, another services API that will not work correctly for the first request after a BE start is Guide/GetChannelIcon? (I ran into that with a tool I wrote years ago, but never did the research to understand the why).

If the root cause is the same, the proposed patch is at best incomplete for registration of all the appropriate API services.

comment:3 Changed 10 months ago by rcrdnalor

I checked the code: For cutom types in namespace DTC of Mythtv Services, QRegisterMetaType is called by InitializeCustomTypes() for each type.

Beside the types in namespace DTC and the C standard types, only these QT types are used in Mythtv Services:

QString
QStringList
QFileInfo

Running a quick test on a freschly booted backend with services returning a QString or a QStringList shows, that those types are already registered to QMetaTypes:

QString:
http://BackendServerIP:6544/Content/GetHash?StorageGroup=Default&FileName=3008_20180808105300.ts
LogFile:
HttpServer56 servicehost.cpp:85 (Invoke) MethodInfo::Invoke: nRetIndx is '10' and type is 'QString'.

QStringList
http://BackendServerIP:6544/Content/GetFileList?StorageGroup=Default
Logfile:
HttpServer55 servicehost.cpp:85 (Invoke) MethodInfo::Invoke: nRetIndx is '11' and type is 'QStringList'.

Therefore I am pretty confident that QFileInfo is the only type for Mythtv's Services, which is not registered at startup.

comment:4 Changed 10 months ago by Roland Ernst <rcrernst@…>

In f7b5fd704/mythtv:

Services API: Allow images/icons immediately after BE startup. Refs #13404

Register <QFileInfo> to QMetaType at backend startup.

Tested on master with:

curl --header Accept:Application/JSON --output /tmp/preview.out \

--silent localhost:6544/Content/GetPreviewImage?RecordedId=<validRID>

curl --header Accept:Application/JSON --output /tmp/icon.out \

--silent localhost:6544/Guide/GetChannelIcon?ChanId=<validChanID>

Also, without --header ... for XML responses.

Required because Services need this type already registered. Without this
fix expect:

JSON: {: }
XML: <?xml version="1.0" encoding="UTF-8"?><></>

Thanks Roland.

Signed-off-by: Bill Meek <billmeek@…>

comment:5 Changed 10 months ago by Roland Ernst <rcrernst@…>

In 26034244e/mythtv:

Services API: Allow images/icons immediately after BE startup. Refs #13404

Register <QFileInfo> to QMetaType at backend startup.

Tested on master with:

curl --header Accept:Application/JSON --output /tmp/preview.out \

--silent localhost:6544/Content/GetPreviewImage?RecordedId=<validRID>

curl --header Accept:Application/JSON --output /tmp/icon.out \

--silent localhost:6544/Guide/GetChannelIcon?ChanId=<validChanID>

Also, without --header ... for XML responses.

Required because Services need this type already registered. Without this
fix expect:

JSON: {: }
XML: <?xml version="1.0" encoding="UTF-8"?><></>

Thanks Roland.

Signed-off-by: Bill Meek <billmeek@…>
(cherry picked from commit f7b5fd704be1e75071f8452b669d303ab053a245)

comment:6 Changed 10 months ago by Bill Meek

Component: MythTV - GeneralMythTV - Services API - Backend
Milestone: 30.129.2

comment:7 Changed 10 months ago by Roland Ernst <rcrernst@…>

Resolution: fixed
Status: acceptedclosed

In 8f37aa3a70/mythtv:

Services API: Allow images/icons immediately after BE startup. Fixes #13404

Register <QFileInfo> to QMetaType at backend startup.

Tested on master with:

curl --header Accept:Application/JSON --output /tmp/preview.out \

--silent localhost:6544/Content/GetPreviewImage?RecordedId=<validRID>

curl --header Accept:Application/JSON --output /tmp/icon.out \

--silent localhost:6544/Guide/GetChannelIcon?ChanId=<validChanID>

Also, without --header ... for XML responses.

Required because Services need this type already registered. Without this
fix expect:

JSON: {: }
XML: <?xml version="1.0" encoding="UTF-8"?><></>

Thanks Roland

Signed-off-by: Bill Meek <billmeek@…>

Note: See TracTickets for help on using tickets.