我想在我的rails应用程序中实现重启作业。首先,我的应用程序非常简单。它只是使用作业播放歌曲形式数据库,我使用循环播放作业中的歌曲以进行无休止的播放。我有播放列表控制器。在此控制器中,有play
方法定义。代码如下:
def play
if @playlist
system "redis-cli flushall"
@playlist.update(current: true)
Playlist.where.not(id: @playlist.id).update_all(current: false)
PlaylistJob.perform_later(@playlist)
@http_status = 200
@http_response = Playlist.all
@http_message = "#{@playlist.name} is now playing...."
else
@http_status = 404
@http_error = { playlist: 'not found' }
@http_message = "Playlist not found"
end
render :json => api_format(0, @http_response , @http_error ,@http_message) , :status => @http_status
end
我的逻辑是,在Playlist
模型中,只能有一行歌曲只能设为真,其他歌曲则为假。所以在将记录更新为current: true
后,处理回放的ActiveJob将perform_later()
。这份工作有这段代码:
class PlaylistJob < ApplicationJob
queue_as :default
def perform(data)# Do something later
system "redis-cli flushall"
ActionCable.server.broadcast 'PlaylistChannel', data
#data is the playlist passed from `PlaylistController`
loop do # endless loop to peform streaming
current_playlist.songs.order('created_at ASC').each do |song|
File.open("public/#{song.track_data.url}") do |file| # open the public URL
m = ShoutMetadata.new # add metadata
m.add 'filename', song.track_data.url
m.add 'title', song.title
m.add 'artist', song.singer
$s.metadata = m
while data = file.read(16384) # read the portions of the file
$s.send data # send portion of the file to Icecast
$s.sync
end
end
prev_song = song # the song has finished playing
end
end # end of the endless loop
end
正如您所看到的,我正在使用ActionCable实时获取传递的播放列表并更新当前播放的播放列表,但每次执行时,播放列表都不会停止并且只会继续播放。我该如何停止这里的活动工作?我已经读过,一旦约伯已经表演并且没有入队,它就不能停止。请帮忙。或者有更好的逻辑可以实现?谢谢。
PS:ActionCable表现良好所以我没有在这篇文章中包含代码。我问的是如何停止作业,以便用户点击前端按钮的下一个播放列表将播放,播放的当前播放列表(使用后台作业sidekiq)将停止。谢谢。