[ 
https://issues.apache.org/jira/browse/THRIFT-3473?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15042770#comment-15042770
 ] 

YU Chang edited comment on THRIFT-3473 at 12/5/15 9:59 AM:
-----------------------------------------------------------

I test my code again and again, and finally I found that the "optional" 
modifier cause the problem.

In the thrift file, the list variable(nBestAlignPairList) and the object 
contained by the list(two string variable in AlignPair), any of them,  can't be 
set to "optional", or, a null/undef  value will be return.

After delete the optional modifier, everything is OK.

Could anybody tell me why I can't use "optional" before a list ?


was (Author: huache):
I test my code again and again, and finally I found that the "optional" 
modifier cause the problem.

In the thrift file, the list variable(nBestAlignPairList) and the object 
contained by the list(two string variable in AlignPair), any of them,  can't be 
set to "optional", or null/undef will be return.

After delete the optional modifier, everything is OK.

Could anybody tell me why I can't use "optional" before a list ?

> When use "optional' before a list, C++ server cannot return it correctly 
> -------------------------------------------------------------------------
>
>                 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:
> {code:title=WordAligner.thrift|borderStyle=solid}
> 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)
> }
> {code}
> Here is my C++ code (server):
> {code:title=WordAlignerServer.cpp|borderStyle=solid}
> #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;
> }
> {code}
> Here is my perl code (client):
> {code:title=WordAlignerClient.pl|borderStyle=solid}
> #!/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 $@;
> {code}
> {code:title=C++ server output|borderStyle=solid}
> nBestAlignPairList size: 1
> src word: 中国
> tar word: china
> {code}
> {code:title=perl client output|borderStyle=solid}
> $VAR1 = bless( {
>                  'resultMessage' => 'Success',
>                  'resultCode' => 0,
>                  'nBestAlignPairList' => undef
>                }, 'WordAligner::AlignResult' );
> {code}
> 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