• 我用过你写的 wechat gem 包,手动点赞😄

  • 这个网站非常好,体现了 vue 的优势,点击首页产品和下载这几个切换非常快,但是点帮助,需要重新打开页面,重新加载会比较再打开首页会比较慢,为什么帮助页面也是用 vue 来写?这样体验就更统一

  • Ruby 回调机制解释 at 2019年10月15日

    原来原理如此,这个文章非常干货,回答了很多工作中遇到的问题👍

  • Ruby 回调机制解释 at 2019年10月15日

    对,就是日常写两个语言感觉不太一样,很想研究一下他们的线程模型

  • Ruby 回调机制解释 at 2019年10月15日

    👍 这个包好,看了一下源码,它用线程实现异步,这个对我帮助很大

  • 不用 redirect_to ,直接调用 another 方法

  • 这个训练模型用了多长时间训练,训练成本需要多少

  • Ruby 回调机制解释 at 2019年10月14日

    看来要看源码了,这个点越学越糊涂😂

  • Ruby 回调机制解释 at 2019年10月14日

    我现在好奇的是要使用回调避免阻塞,其前提应该是需要使用多线程,否则无论如何在单线程上一定会阻塞的,关于 ruby 的线程,其实也是越学越糊涂, 1.最早是看<松本行弘的编程世界>和 matz 自己提到过 ruby 最后悔的是线程的设计,因为他使得语言变得复杂,而且他说线程这个功能是后来匆忙加上去的,对于是否单线程,matz 本人好像没有说,但是我猜测是单线程的.

    1. 我帮别人做过一个项目,在做 amazon 的云存储时,文档明确介绍的是如果使用 js 或者 ruby 这样的语言读取文件的时候,是会阻塞应用程序的. 3.另外还有文章说,ruby 的县城取决于操作系统和编译器 https://cloud.tencent.com/developer/ask/51206 如这篇文章所述. 所以各个说法都不一样,而目前又没有不太会读 ruby 的源码,所以一直都比较困惑,如你所述如果 ruby 不是单线程,那么可以怎么证明?
  • 终于在@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 到另一种语言,那就是语言的编译和移植