Skip to main content
 首页 » 编程设计

python之节俭 python之TApplicationException : Invalid method name

2025年05月04日21bonelee

我在同一个 thrift 文件中定义了 2 个服务并共享一个端口。我可以使用 serviceA 中的任何方法没问题,但每当我尝试调用 ServiceB 的任何方法时,我都会遇到异常。 这是我的节俭文件 (service-a.thrift):

service ServiceA extends common.CommonService { 
    list<i64> getByIds(1: list<i64> ids) 
    ... 
} 
 
service ServiceB extends common.CommonService { 
    list<i64> getByIds(1: list<i64> ids) 
    ... 
} 

注意事项:

  • 我正在使用 python 客户端
  • Thrift 版本 0.8.0

有什么想法吗?

请您参考如下方法:

我们也有这个需求,并通过编写一个新的 TProcessor 实现来解决,该实现创建了一个多处理器映射。唯一的问题是,对于此实现,您需要确保没有方法名称重叠 - 即不要在不同的服务器中使用像 Run() 这样的通用名称。抱歉没有将 C# 转换为 Python...

示例类:

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.IO; 
using System.Reflection; 
using Thrift; 
using Thrift.Protocol; 
 
/// <summary> 
/// Processor that allows for multiple services to run under one roof.  Requires no method name conflicts across services. 
/// </summary> 
public class MultiplexProcessor : TProcessor { 
 
    public MultiplexProcessor(IEnumerable<TProcessor> processors) { 
        ProcessorMap = new Dictionary<string, Tuple<TProcessor, Delegate>>(); 
        foreach (var processor in processors) { 
            var processMap = (IDictionary) processor.GetType().GetField("processMap_", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(processor); 
            foreach (string pmk in processMap.Keys) { 
                var imp = (Delegate) processMap[pmk]; 
                try { 
                    ProcessorMap.Add(pmk, new Tuple<TProcessor, Delegate>(processor, imp)); 
                } 
                catch (ArgumentException) { 
                    throw new ArgumentException(string.Format("Method already exists in process map: {0}", pmk)); 
                } 
            } 
        } 
    } 
 
    protected readonly Dictionary<string, Tuple<TProcessor, Delegate>> ProcessorMap; 
 
    internal protected Dictionary<string, Tuple<TProcessor, Delegate>> GetProcessorMap() { 
        return new Dictionary<string, Tuple<TProcessor, Delegate>>(ProcessorMap); 
    } 
 
    public bool Process(TProtocol iprot, TProtocol oprot) { 
        try { 
            TMessage msg = iprot.ReadMessageBegin(); 
            Tuple<TProcessor, Delegate> fn; 
            ProcessorMap.TryGetValue(msg.Name, out fn); 
            if (fn == null) { 
                TProtocolUtil.Skip(iprot, TType.Struct); 
                iprot.ReadMessageEnd(); 
                var x = new TApplicationException(TApplicationException.ExceptionType.UnknownMethod, "Invalid method name: '" + msg.Name + "'"); 
                oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID)); 
                x.Write(oprot); 
                oprot.WriteMessageEnd(); 
                oprot.Transport.Flush(); 
                return true; 
            } 
 
            Console.WriteLine("Invoking service method {0}.{1}", fn.Item1, fn.Item2); 
            fn.Item2.Method.Invoke(fn.Item1, new object[] {msg.SeqID, iprot, oprot}); 
        } 
        catch (IOException) { 
            return false; 
        } 
        return true; 
    } 
} 

示例用法:

        Processor = new MultiplexProcessor( 
            new List<TProcessor> { 
                                     new ReportingService.Processor(new ReportingServer()), 
                                     new MetadataService.Processor(new MetadataServer()), 
                                     new OtherService.Processor(new OtherService()) 
                                 } 
            ); 
        Server = new TThreadPoolServer(Processor, Transport);