威海路 696 号 WeWork
whenever 是用的系统的 crontab,到不了秒级,每次启动都要重新加载整个项目,又慢又没必要。
用 cron 合适。sidekiq 应该是用 redis 的 sorted set 实现 perform_later,如果你需要发的邮件多的话这个 set 会很大。用 cron(sidekiq 的 cron)的话就没这个问题,效果也差不多。
你要不就把不需要 autoreolad 的代码择出来放 initializer 里,要不就在 concern module 里 lazy load (@xxx ||= begin ... end
可能需要加线程锁)
读文件代码不放 concerns 里,只放 initializer 里不就好了。
# initializers/xxx.rb
MY_CONST = File.read(file_name)
# controllers/concerns/xxx.rb
module Xxx
MY_CONST2 = MY_CONST
end
那就应该是你网络问题了。(以下是推论,没自己实际测试过)
当你改动代码的时候,rails 会清 databse connection https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railtie.rb#L248
然后新请求会尝试建立数据库链接,但是比较慢,就看到 log 了。console 用ActiveRecord::Base.connection_pool.send(:new_connection)
单独测一下你连阿里云数据库需要多长时间吧
提供一个思路,你可以在ActiveRecord::LogSubscriber#sql
源代码里加一些 debug 信息,然后新建一个 rails 项目,console 里用ActiveRecord::Base.connection_pool.send(:new_connection)
模拟新建一个数据连接来看是不是也很慢。
先说输出这些 log 是在哪里:
输出 sql 到 log 是https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L680-L695 跟 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/log_subscriber.rb#L22-L44 做的
你可以在这里设断点来调试(改 gem 代码记得先 spring stop 才能重新加载你改过的代码)
再说你遇到的现象: 你的环境老是要重新新建数据库连接,而且还挺慢。这应该跟你本地数据库有关系,不像 rails 这边的问题。正常 rails 本地环境不需要如此频繁的建立数据库连接。建议从 mysql 这边找原因。
class Sample
class << self
# 4空格缩进是类方法
def class_method
end
private
# 6空格缩进是私有类方法
def private_class_method
end
end
# 2空格缩进是实例方法
def instance_method
end
private
# 下区4空格缩进是私有实例方法
def private_instance_method
end
end
Rails 建议用class << self
https://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions
Prefer class << self over self.method for class methods.
可以再成立一个MandarinCademy
了
大家好,我是 Mehdi
来自法兰西的大兄弟? https://medium.com/@farsi_mehdi
当&xxx
是一个方法的最后一个参数时,会认为最后一个参数是一个 proc,并调用xxx.to_proc
把xxx
转化成 proc
data1.map(&:to_sym)
相当于
proc = :to_sym.to_proc
data1.map &proc
任何对象能响应to_proc
方法都可以这样写
class X
def to_proc
Proc.new { puts "xxxx" }
end
end
[1, 2, 3].each &X.new
fiber 是线程的替代品,mysql2 是一个客户端,用不上,要用也是 active record 的线程池。用的最多的还是 server 编程
离我家好近
非常的不想要 prefix attribute name
Rails 6 可以 override model attribute 级别的 error format https://blog.bigbinary.com/2019/04/22/rails-6-allows-to-override-the-activemodel-errors-full_message-format-at-the-model-level-and-at-the-attribute-level.html
我们不说“平庸”,“低水平”,我们说平均水平
软件工程目的真的就是为了实现低水平的程序员都能完成工作?
软件工程的目的是利用现有资源完成目标。精英工程师是稀缺资源,绝大部分公司不可能全员精英,如何利用好平均水平工程师才是关键。
还是优秀人才难招聘(或者不愿招聘)、难培养(或者没能力培养)的结果?
同上点,优秀人才稀缺是不可改变的现实,请不要把人才培养的责任推给企业,企业顶多占 20%,个人因素最重要。
“
平庸平均水平员工就能以可接受质量完成工作”是我们应该追求的目标?
是。
公司隐含的要求是:员工要能解决问题,并且还要平庸,所以让员工变得平庸的技术反而能大行其道。
是不是有点因果倒置,平庸员工都能解决问题的技术就应该大行其道。别人都上先进生产线,招高中毕业生,培训 2 天直接上岗,你还非要找 20 年经验老手工师傅。当然不是说老手工师傅不行,只是适合的场景不一样。
有不少公司招新人进来不让接触根本的东西,自己封装了一层“指导原则”的东西,招进来的人在这个框架上工作,甚至连编程语言(Ruby)本身、技术框架(Rails)本身都没怎么掌握,就被赶鸭子上架,照葫芦画瓢的 copy and paste 写代码。
copy paste 写代码跟公司没什么关系,没有公司会禁止员工进步。就软件行业来说,大批优秀开源项目、文章等学习资料唾手可得,进步不了怪公司有点说不过去。
总结:平庸员工就能以可接受质量完成工作是生产方式优秀的体现,有上进心的人可以没有障碍(科学上网不算)的接触业界先进知识是行业优秀的体现。
你需要的是子方法跳出到父方法的能力,考虑一下用catch
跟throw
def fun
r = catch(:tag) do
a_fun
b_fun
...
return 0
end
return r
end
只有我名字没打码,明显是冲我来的
Raft 是一个复制 log 的算法
Raft 是解决分布式系统一致性的算法,log 其实是 commit log,不说明一下容易产生歧义。
哪个资本闲着没事还去宣传技术?
Rails 本身不适合业务急速扩张的场景,倒不是 Ruby 本身的 scalability 问题,是团队的 scalability 问题。急速扩张大量需求的是蓝领工程师,Rails 作为蓝领工具没有特别优势,甚至还有不少劣势。
归根结底还是因为软件相关行业利润太高,能堆人解决的问题都不是问题;rails 工程师大多是 generalist,堆人的公司也用不上。
JSON.generate(hash, space: " ", indent: " ").sub(/\s/, '')
require "socket"
require "nio"
def run(host, port)
server = TCPServer.new(host, port)
puts "Listening to #{host}:#{port}"
selector = NIO::Selector.new
monitor = selector.register(server, :r)
monitor.value = ->(_) do
socket = server.accept
puts "New client #{socket}"
client_monitor = selector.register(socket, :r)
client_monitor.value = ->(mon) do
s = mon.io
puts "Got: #{s.read_nonblock(4096)}"
end
end
loop do
selector.select { |monitor| monitor.value.call(monitor) }
end
end
run('localhost', 1234)
Puma 是多个地方用到IO.select
,reactor 从IO.select
替换到NIO::Selector#select
https://github.com/puma/puma/commit/e83a4954e4c0214d18beb594ddf598fafdf058d7#diff-8b7db4d5cc4b8f6dc8feb7030baa2478
IO.select 跟 NIO::Selector 的区别官方 wiki 就有 https://tonyarcieri.com/a-gentle-introduction-to-nio4r
是 Thread B 里的selector.select do |monitor|
block Thread A 里的monitor = selector.register(socket, :r)
NIO:: Selector#select
是IO.select
的替代品,不应该同时用。NIO:: Selector#select
。server monitor 的 callback 里接收客户端 io 对象,然后把 io 对象再注册到 nio selector 里。我那句提反转二叉树了?贴个老梗显得自己懂得多?一个极端特例当论据是不是抬扛?一直用反问句回复别人是不是自我感觉很良好?