make normalize_key cpdef & add warnings for unpickle unmarshal fail#66
make normalize_key cpdef & add warnings for unpickle unmarshal fail#66MOON-CLJ merged 3 commits intodouban:masterfrom
Conversation
4abf267 to
aeeb318
Compare
0a82963 to
c1a0626
Compare
libmc/_client.pyx
Outdated
| try: | ||
| dec_val = marshal.loads(dec_val) | ||
| except: | ||
| warnings.warn("[libmc] unmarshal failed %r" % dec_val) |
There was a problem hiding this comment.
dec_val 是 二进制应该没什么用吧,还比较大
There was a problem hiding this comment.
okay,考虑把key和error都打出来。
There was a problem hiding this comment.
@youngsofun 应该不用key,get 知道自己是什么key,get_multi至少知道范围。
libmc/_client.pyx
Outdated
| flags[0] = _FLAG_PICKLE | ||
| except: | ||
| pass | ||
| warnings.warn("[libmc] marshal & pickle both failed %r" % val) |
There was a problem hiding this comment.
还有 pickle 失败的信息里可能也有有用的信息
c1a0626 to
5879666
Compare
libmc/_client.pyx
Outdated
| except: | ||
| pass | ||
| except Exception as e: | ||
| warnings.warn("[libmc] marshal & pickle both failed. type:%r err:%r" % (type_, e)) |
There was a problem hiding this comment.
This may lead to a log flood if the unpackable object is encoded again and again.
There was a problem hiding this comment.
@mckelvin #66 (comment) as i explain,it only output at the first time for each msg in warnings.warn(msg)。https://gist.github.com/MOON-CLJ/0f06a1e57d872c6f5f0f9e368326d406 this gist try to make it more clear。
so i think it's enough to avoid log flood in most case。
| alias = PyUnicode_AsUTF8String(alias) if alias else None | ||
| servers_.append((host, port, alias)) | ||
|
|
||
| Py_INCREF(servers_) |
There was a problem hiding this comment.
As is described in the doc:
The PyString_AsString return a NUL-terminated representation of the contents of string. The pointer refers to the internal buffer of string, not a copy.
So I think c_hosts[i] is using the host string object, which is inside the servers_.
There was a problem hiding this comment.
@mckelvin okay, i'll revert this change.(still not very sure as follow comment)
There was a problem hiding this comment.
@mckelvin but i am still not very clear about this line https://github.com/douban/libmc/pull/66/files#diff-721f906017b85cb2e3838d0775a3138dR376
host, port, alias = servers_[i]
host, port, alias is copy or ref?
if it's copy(new variable),Py_INCREF(severs_) is not necessary。
There was a problem hiding this comment.
confirm by @windreamer , it's ref。i'll revert this change。
In [14]: a = 1
In [15]: servers = [[a, 1, 2]]
In [16]: _a, _, _ = servers[0]
In [17]: id(_a)
Out[17]: 24355160
In [18]: id(a)
Out[18]: 24355160
There was a problem hiding this comment.
to say the least, servers_ is a func local variable, it's lifetime will expand to the whole func。
so i doubt Py_INCREF(servers_) is just a programming style?
libmc/_client.pyx
Outdated
| dec_val = marshal.loads(dec_val) | ||
| except: | ||
| except Exception as e: | ||
| warnings.warn("[libmc] unmarshal failed. err:%r" % e) |
There was a problem hiding this comment.
Same log flood issue here.
libmc/_client.pyx
Outdated
| dec_val = pickle.loads(dec_val) | ||
| except: | ||
| except Exception as e: | ||
| warnings.warn("[libmc] unpickle failed. err:%r" % e) |
There was a problem hiding this comment.
Same log flood issue here.
| else: | ||
| self._imp.disableConsistentFailover() | ||
|
|
||
| PyMem_Free(c_hosts) |
There was a problem hiding this comment.
These 3 lines are moved to earlier lines. Why?
There was a problem hiding this comment.
because @everpcpc's pr https://github.com/douban/libmc/pull/74/files#diff-721f906017b85cb2e3838d0775a3138dR418 already do this, i'll revert this change。
|
I'd appreciate it if you could polish the PR and git commit message: https://chris.beams.io/posts/git-commit/ |
thx very much , i will try。 |
5879666 to
08b7690
Compare
1010f18 to
c9cb4d7
Compare
c9cb4d7 to
871dd04
Compare
this ci include some minor fixes: - c_server_addr to server_addr, because it's basestring not c char array. - c_hosts c_ports c_aliases PyMem_Free after _imp.init immediately, _imp.init dont take over their buffer,_imp.init use snprintf to make copy,so i think free as soon possible do the right thing。
871dd04 to
cc83b57
Compare
|
@MOON-CLJ 从你的 demo看,"首次" 是完全基于log msg 文本的吗?
https://github.com/python/cpython/blob/3.6/Lib/pickle.py#L265 所以,可能需要对 err 做裁剪? 后者要引用代码证明不存在上述问题)。 另外没有 key, 定位可能比较麻烦 cython 我写的少,细节如果不放心再找田老师确认一下? |
基本上是,即warnings.warn所在的行数加上warnings.warn的内容去重。https://gist.github.com/MOON-CLJ/0f06a1e57d872c6f5f0f9e368326d406
https://gist.github.com/MOON-CLJ/0f06a1e57d872c6f5f0f9e368326d406/revisions#diff-1ad944627ac1ed425afb954cf0f6f757L46 从这里判断,对于libmc的情况,出错时,会将调用libmc get方法那一行打印出来,定位也就够了?用法定位到了,也就不用key了? 所以问题应该集中在pickle或者unpickle error的出错信息上?我再确认下。 |
不过对于cache deco这种集中调用get的地方不适用。 |
验证了下,确实会有风险。 |
|
@youngsofun https://gist.github.com/MOON-CLJ/0f06a1e57d872c6f5f0f9e368326d406 gist updated how about just print value type and stack? |
|
@MOON-CLJ 感觉, libmc 内部 调用 decode 位置固定, key 应该可以在 上一两层的 python frame 对象中找到? 和 stack 一样 单独 log 出来即可。先要确定 不是外部的调用 |
|
@youngsofun https://gist.github.com/MOON-CLJ/0f06a1e57d872c6f5f0f9e368326d406#file-python-warnings-warn-test-L75 将拿key的逻辑写在这个function里感觉也有点奇怪。 |
|
@MOON-CLJ 可以先这样上,遇到具体问题再说 |
cc83b57 to
86ca251
Compare
|
直接 改 warnings,似乎不妥? 其他人也用呢? |
|
@youngsofun 嗯 也是哈。我再想想。 |
warning about pickle and marshal err when encode_value or decode_value
d16eac9 to
583e147
Compare
|
@youngsofun updated |
ChangeLog: - use pickle protocol version 2 (#52) - fix rvalue reference (#53) - Fix tests (#55) - golibmc_test: Fix fragile test case (#56) - Use connection pool in golibmc(again) (#57) - golibmc Quit ret err (#59) - cmake: Incorporate gtest in a standard way (#58) - Rename refactor (#60) - sync rapidjson/itoa.h upstream fix (#65) - split cppcheck (#67) - split FSM_GET_BYTES_CAS (#68) - Avoid noisy recv_err when broadcast quit (#73) - Try to support updating some servers without affecting others (#74) - make normalize_key cpdef & add warnings for unpickle unmarshal fail (#66) - fix fcntl usage when set socket nonblock (#69) - minor fix (#61) - add condition log macro (#77) - Define and use notWaitForRetryTimeout (#82) - upgrade travis to gcc 7 (#91) - add func errCodeToString (#79) - Introduce a reconnect mechanism in waitPoll (#88)
warnings.warn for unpickle & unmarshal fail, and only first time for each line of the caller code。