ProtoBuf消息上的SerializeToString()方法包含必需的字段,这些字段具有默认值,始终会抛出EncodeError消息缺少必需字段的消息.但是,如果我检查字段的值,则会设置所有默认值.例如:
// mymessage.proto
message MyMessage {
required int32 val = 1 [default=18];
}
Run Code Online (Sandbox Code Playgroud)
然后在python中:
from mymessage_pb2.py import MyMessage
m = MyMessage()
print m.val # Shows m.val == 18
print m.SerializeToString() # EncodeError
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我这样做:
m.val = m.val
print m.SerializeToString() # No Error
Run Code Online (Sandbox Code Playgroud)
很清楚,尽管在初始化时有一个默认值,但它只需要触摸每个字段.对我来说,默认的一个主要观点是只需要有人来更新非默认字段(或者他们需要更改的那些字段),所以这个set-it-to-own方法是一个非常令人遗憾的解决方案.
将字段标记optional为不是解决方案,因为根据我们的规范,这些字段是合法需要的.
更新:我尝试合作包括MergeFrom和CopyFrom,但都没有奏效.所以我写了这个:
def ActuallyInit(obj):
err = []
obj.IsInitialized(err)
for field in err:
attr = obj.__getattribute__(field)
try:
obj.__setattr__(field, attr)
except:
ActuallyInit(attr)
Run Code Online (Sandbox Code Playgroud)
然后一个人创建他们的protobuf对象并将其传递到ActuallyInit其中,递归地将每个字段设置为自己.这看起来像是一个丑陋的黑客,所以我将问题留在下面.
问题:有没有办法创建ProtoBuf消息实例并"说服"它每个已经初始化为默认的字段实际上不是错误?
我正在将Angular 2.1用于具有多个子模块的大型应用程序,每个子模块定义按功能组织的子应用程序.顶级模块通过导入每个子应用程序的路由等,为整个应用程序配置路由器模块以及所有子路由.因此,从子应用程序的角度来看,它相对于顶层应用程序设置路由的路由,但是子应用程序没有直接明确地知道它的主要路由实际是什么.
其中一些子应用程序具有在另一个子应用程序中更完全定义/控制的实体的摘要面板.从概念上讲,模块的设置如下:
Module 1:
Imports Module 2
Routes for Module 1
Component1A
App1View (contains Component1A, M2SummaryComponent)
Module 2:
Routes for Module 2 (one exported as APP2_VIEW_ROUTE, type Route)
Component2A
Component2B
M2SummaryComponent
App2View (contains Component2A, Component2B)
...etc.
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种设计模式,借此可以编写M2SummaryComponent链接到其自己模块中的路径,同时在模块1的App1View中实例化,而无需以某种方式手动硬编码或重新组装路径.
我曾经希望这是一个普遍存在的问题,Angular团队可能会使用类似的东西router.navigate([APP2_VIEW_ROUTE, ...other params]),只需传递你用来配置与所需路径相关的RouterModule的路由对象.看一下源代码,但这似乎不是一个选择.相反,我们有ActivatedRoute的例子.
ActivatedRoute(this.route下面)面临的问题是它将相对于App1View.所以尝试使用router.navigate(['m2SpecialId'],{relativeTo: this.route})是非首发,因为它将相对于让我们进入App1View的路径,而不是回到模块2的首选App2View路径.
就我所知,围绕这些问题的唯一另一个有点优雅的路线(双关语)是使每个子应用程序的模块可以作为ModuleWithProviders导入,以便可选地,可以通知模块的顶级路由适用于其州.然后编写辅助函数,使用其定义的路由汇编特定于该子应用程序的URI.
这感觉很锅炉......就像框架中已经存在解决方案或设计模式一样,因此这个问题.
题:
是否存在使用Angular2路由器的设计模式,该模式允许导入其他模块的组件干净地引用其自己模块的预配置路由,同时保持灵活的顶级路由定义?
我有比这更多的代码,所以我把它修改为看似相关的东西.根据记录的示例,我有一个用于ZeroRPC的python类:
import zerorpc, sys, signal
class MyClass:
pass
zpc = 0
if __name == '__main__':
zpc = zerorpc.Server(MyClass)
zpc.bind('ipc://./mysocket.sock')
zpc.run()
print("zpc stopped"); sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
python脚本从我的Node.js服务器生成为ChildProcess,它监听stdout和stderr.当客户端连接超时或服务器关闭时,我在ChildProcess上调用kill(),它向它发送SIGTERM.
仅使用上面的代码,'zpc stopped'永远不会在Node.js回调中捕获,这表明ZeroRPC服务器在其运行循环中的某处被杀死.此外,套接字文件仍然存在,表明服务器也没有关闭套接字.所以我想在捕获SIGTERM后我会在服务器上调用stop()或close():
def sig_handle (signal, frame):
global zpc
print("SIGTERM received.") # <-- this does occur
zpc.stop() # <-- Exception thrown here and at run()
sys.exit(0)
signal.signal(signal.SIGTERM, sig_handle)
Run Code Online (Sandbox Code Playgroud)
Node.js通过其stderr回调获取异常:
Gateway Error: File "/usr/lib/python2.6/site-packages/zerorpc/core.py", line 178, in stop
Gateway Error: self._acceptor_task.kill()
File "/usr/lib64/python2.6/site-packages/gevent/greenlet.py", line 235, in kill
Gateway Error: waiter.get()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 568, in get
Gateway Error: …Run Code Online (Sandbox Code Playgroud)