jam-cloud/web/lib/music_session_manager.rb

153 lines
5.7 KiB
Ruby

class MusicSessionManager < BaseManager
def initialize(options={})
super(options)
@log = Logging.logger[self]
end
def create(music_session, user, client_id, description, musician_access, approval_required, fan_chat, fan_access, band, genres, tracks, legal_terms, audio_latency)
return_value = nil
time = Benchmark.realtime do
ActiveRecord::Base.transaction do
# we need to lock the icecast server in this transaction for writing, to make sure thath IcecastConfigWriter
# doesn't dumpXML as we are changing the server's configuraion
icecast_server = IcecastServer.find_best_server_for_user(user) if fan_access
icecast_server.lock! if icecast_server
# check if we are connected to rabbitmq
active_music_session = ActiveMusicSession.new
active_music_session.id = music_session.id # copy the .id from music_session to active_music_session
active_music_session.creator = user
if fan_access
# create an icecast mount since regular users can listen in to the broadcast
active_music_session.mount = IcecastMount.build_session_mount(music_session, active_music_session, icecast_server)
end
active_music_session.save
unless active_music_session.errors.any?
# save session parameters for next session
User.save_session_settings(user, music_session)
# auto-join this user into the newly created session
as_musician = true
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency)
unless connection.errors.any?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(active_music_session.id, user.id, client_id, tracks)
# only send this notification if it's a band session
unless band.nil?
Notification.send_band_session_join(active_music_session, band)
end
return_value = active_music_session
else
return_value = connection
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
else
return_value = active_music_session
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
end
end
if time > 2
@log.warn "creating a music session took #{time*1000} milliseconds"
end
return_value
end
# Update the session. If a field is left out (meaning, it's set to nil), it's not updated.
def update(music_session, name, description, genre, language, musician_access, approval_required, fan_chat, fan_access)
music_session.name = name unless name.nil?
music_session.description = description unless description.nil?
music_session.genre = genre unless genre.nil?
music_session.language = language unless language.nil?
music_session.musician_access = musician_access unless musician_access.nil?
music_session.approval_required = approval_required unless approval_required.nil?
music_session.fan_chat = fan_chat unless fan_chat.nil?
music_session.fan_access = fan_access unless fan_access.nil?
music_session.save
music_session
end
def participant_create(user, music_session_id, client_id, as_musician, tracks, audio_latency)
connection = nil
music_session = nil
ActiveRecord::Base.transaction do
active_music_session = ActiveMusicSession.find(music_session_id)
active_music_session.with_lock do # VRFS-1297
active_music_session.tick_track_changes
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency)
if connection.errors.any?
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
end
end
unless connection.errors.any?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(music_session_id, user.id, client_id, tracks)
if as_musician
# send to session participants
Notification.send_session_join(active_music_session, connection, user)
music_session = active_music_session.music_session
# send "musician joined session" notification only if it's not a band session since there will be a "band joined session" notification
if music_session.band.nil?
Notification.send_musician_session_join(music_session, user)
end
end
end
connection
end
def participant_delete(user, connection, active_music_session)
if connection.user.id != user.id
raise JamPermissionError, "you do not own this connection"
end
recordingId = nil
active_music_session.with_lock do # VRFS-1297
ConnectionManager.new.leave_music_session(user, connection, active_music_session) do
active_music_session.tick_track_changes
recording = active_music_session.stop_recording # stop any ongoing recording, if there is one
recordingId = recording.id unless recording.nil?
end
end
Notification.send_session_depart(active_music_session, connection.client_id, user, recordingId)
end
def sync_tracks(active_music_session, client_id, new_tracks, backing_tracks, metronome_open)
tracks = nil
active_music_session.with_lock do # VRFS-1297
tracks = Track.sync(client_id, new_tracks, backing_tracks, metronome_open)
active_music_session.tick_track_changes
end
Notification.send_tracks_changed(active_music_session)
tracks
end
end