大佬能留个微信么,或者邮箱,我要投简历,我的微信 15220220554
我用过你写的 wechat gem 包,手动点赞
原来原理如此,这个文章非常干货,回答了很多工作中遇到的问题
对,就是日常写两个语言感觉不太一样,很想研究一下他们的线程模型
这个包好,看了一下源码,它用线程实现异步,这个对我帮助很大
不用 redirect_to ,直接调用 another 方法
这个训练模型用了多长时间训练,训练成本需要多少
看来要看源码了,这个点越学越糊涂
我现在好奇的是要使用回调避免阻塞,其前提应该是需要使用多线程,否则无论如何在单线程上一定会阻塞的,关于 ruby 的线程,其实也是越学越糊涂, 1.最早是看<松本行弘的编程世界>和 matz 自己提到过 ruby 最后悔的是线程的设计,因为他使得语言变得复杂,而且他说线程这个功能是后来匆忙加上去的,对于是否单线程,matz 本人好像没有说,但是我猜测是单线程的。
终于在@rails/webpacker/packages/enviorments/production.js 找到了原因
module.exports = class extends Base {
constructor() {
super()
this.plugins.append(
'Compression',
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
cache: true,
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
})
)
this.plugins.append(
'OptimizeCSSAssets',
new OptimizeCSSAssetsPlugin({
parser: safePostCssParser,
map: {
inline: false,
annotation: true
}
})
)
this.config.merge({
devtool: 'source-map',
stats: 'normal',
bail: true,
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
sourceMap: true,
terserOptions: {
parse: {
// Let terser parse ecma 8 code but always output
// ES5 compliant code for older browsers
ecma: 8
},
compress: {
ecma: 5,
warnings: false,
comparisons: false
},
mangle: {
safari10: true
},
output: {
ecma: 5,
comments: false,
ascii_only: true
}
}
})
]
}
})
}
}
注释掉这个插件即可
// this.plugins.append(
// 'OptimizeCSSAssets',
// new OptimizeCSSAssetsPlugin({
// parser: safePostCssParser,
// map: {
// inline: false,
// annotation: true
// }
// })
// )
我发现是我理解错了,原来是 rescue ActiveRecord::RecordInvalid 的时候,render 的时候又抛出错误了,然后新的错误就在错误的数组上新增,这个是没问题的,是我对 rescue 的机制认识不够深入
对的就是这个错误,但是后面 rescue 的时候,把 activerecord 的错误抛给我了,实际上应该是 missing template 的,但是我觉得既然我 rescue 了 activerecord::invalid,后面就不应该显示这个错误,只显示 missingtemplate 就好了,这个不影响功能,但是可以优化
通过一级一级调用往上找,终于找到原因了, /home/linqining/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/actionpack-5.2.2.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
21: def process_action(*args)
22: super
23: rescue Exception => exception
=> 24: binding.pry
25: request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
26: rescue_with_handler(exception) || raise
27: end
原因是在 rescue, binding 显示的事 missing template,controller 中的方法的确没有 render json,导致没有 missing template, 而后面的错误处理 rescue_with_handler 把 activerecord 的错误一并处理,并且先显示 activecord 的错误 (这里不清楚 rescue 的错误优先顺序,知悉的大神告诉一下),我猜测 rescue 显示错误的时候是根据上下文出现的顺序显示的,显示 activecord record 引起的错误,然后是 missing template 引起错误,
def create
@order = Order.new(params.require(:order).permit!)
begin
ActiveRecord::Base.transaction do
puts caller_locations
@order.save!
end
respond_to do |format|
format.html do
redirect_to order_path(@order)
end
format.json do
render json: {status:200, message: ''}
end
end
rescue ActiveRecord::RecordInvalid
respond_to do |format|
format.html do
render :new
end
format.json do
render json: {status:200, message: ''}
end
end
rescue StandardError=>e
flash[:notice] = e
respond_to do |format|
format.html do
render :new
end
format.json do
render json: {status:200, message: ''}
end
end
end
end
根据请求的类型,返回相应的数据就解决问题了
这次的疑惑是 rescue 的处理顺序带来的,既然 activerecord 已经捕捉错误了,后面显示错误的时候,是否应该只应显示 render template missing 的错误?至少有个地方可以改进 1.能否根据请求的格式自动选择相应的格式,这样即使是出现错误,没有指明返回收据类型,返回 204 no_content 更符合实际,而不是返回 500
继续调试跟进 在@order.save之前输出 caller_locations (因为最近的错误就是@order.save!,往后就是报错,拿不到 caller_locations)
def create
@order = Order.new(params.require(:order).permit!)
begin
ActiveRecord::Base.transaction do
puts caller_locations
@order.save!
end
redirect_to order_path(@order)
rescue ActiveRecord::RecordInvalid
render :new
rescue StandardError=>e
flash[:notice] = e
render :new
end
end
发现这两种方法请求在报错前,调用完全一样,那么可能是调用过程某些参数不一样,沿着调用方法一层层对比参数试一下
new 对象不会报错的,而且 ActiveRecord::InvalidError 这个是验证错误,save! 这个方法跑出异常的 (因为 ActiveRecord 只能抛出异常触发回滚),和异步请求无关,现在问题是,不同的请求格式竟然引起可能导致 rescue 不执行!!!??? 这是框架的原因,排查很久不知道为什么请求格式会引起 rescue 不起作用
同意,真正做一门语言离不开 c 和 c++,因为需要和硬件交互,如果在 ruby 的基础上开发,移植更合适
如果做语言的话,ruby 适合做 dsl, 如果要重新发明一个语言,不建议使用 ruby,因为效率太低 如果是从 ruby 到另一种语言,那就是语言的编译和移植