YU Chang created THRIFT-3473:
--------------------------------

             Summary: C++ server cannot correctly return a struct/object 
contains list
                 Key: THRIFT-3473
                 URL: https://issues.apache.org/jira/browse/THRIFT-3473
             Project: Thrift
          Issue Type: Bug
          Components: C++ - Library
    Affects Versions: 0.9.3
         Environment: CentOS 7, GCC 4.8.3, Perl 5.16
            Reporter: YU Chang


When a struct/object contains list, the thrift C++ server always return 
null/undef.

Here is my thrift file:

namespace cpp WordAligner
namespace perl WordAligner

struct AlignParamter {
    1: string srcLang,
    2: string tarLang,
    3: optional i32 nBestSize = 1,
}

struct SentenPair {
    1: string srcSenten,
    2: string tarSenten,
}

struct AlignPair {
    1: optional string srcWord,
    2: optional string tarWord,
}

struct AlignResult {
    1: i32 resultCode,
    2: string resultMessage,
    3: optional list<list<AlignPair>> nBestAlignPairList,
}

service WordAlignService {
    AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair 
sentenPair),
    list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: 
list<SentenPair> sentenPairList)
}

Here is my C++ code (server):

#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

#include "thrift/WordAlignService.h"

#include <iostream>
#include <cstdlib>

using namespace std;
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

using namespace  ::WordAligner;

class WordAlignServiceHandler : virtual public WordAlignServiceIf {
    public:
        WordAlignServiceHandler() {
        }

        void alignOnePair(AlignResult& _return, const AlignParamter& 
alignParamter, const SentenPair& sentenPair) {
            _return.resultCode = 0;
            _return.resultMessage = "Success";
            AlignPair alignPair;
            alignPair.srcWord = "中国";
            alignPair.tarWord = "china";
            vector<AlignPair> alignPairVec;
            alignPairVec.push_back(alignPair);
            _return.nBestAlignPairList.push_back(alignPairVec);
            cout << "nBestAlignPairList size: " << 
_return.nBestAlignPairList.size() << endl;
            cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord << 
endl;
            cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord << 
endl;
        }

        void alignPairList(std::vector<AlignResult> & _return, const 
AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) {
            // Your implementation goes here
            printf("alignPairList\n");
        }

};

int main(int argc, char **argv) {
    int port = 9595;
    shared_ptr<WordAlignServiceHandler> handler(new WordAlignServiceHandler());
    shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(handler));
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new 
TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, 
protocolFactory);
    server.serve();
    return 0;
}

Here is my perl code (client):

#!/usr/bin/perl

use v5.12;
use warnings;
use autodie;

use utf8;
use Data::Dumper;

use lib 'gen-perl-wordalign';

use WordAligner::WordAlignService;
use WordAligner::Constants;
use WordAligner::Types;

use Thrift;
use Thrift::BinaryProtocol;
use Thrift::Socket;
use Thrift::BufferedTransport;


my $socket    = new Thrift::Socket('localhost', 9595);
my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
my $protocol  = new Thrift::BinaryProtocol($transport);
my $client    = new WordAligner::WordAlignServiceClient($protocol);

my $align_param = new WordAligner::AlignParamter;
$align_param->srcLang('zh-CN');
$align_param->tarLang('en');

my $src_senten = "中国 政府 高度 重视 经济 发展 。";
my $tar_senten = "china 's government attached great importance to economic 
development .";

my $senten_pair = new WordAligner::SentenPair;
$senten_pair->srcSenten($src_senten);
$senten_pair->tarSenten($tar_senten);

eval {
    $transport->open();
    my $result = $client->alignOnePair($align_param, $senten_pair);
    say Dumper($result);
    $transport->close();
};
say $@ if $@;

C++ server output:

nBestAlignPairList size: 1
src word: 中国
tar word: china

perl client output:

$VAR1 = bless( {
                 'resultMessage' => 'Success',
                 'resultCode' => 0,
                 'nBestAlignPairList' => undef
               }, 'WordAligner::AlignResult' );

For solving this problem, I have already tried to:

1) return just one level list, not list of list;
2) using C++ client to test;
3) upgrade thrift version from 0.9.1 to 0.9.3;

But nothing help, the return list is still empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to