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 active_music_session.school_id = user.school_id active_music_session.is_platform_instructor = user.is_platform_instructor 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? music_session.started_at = active_music_session.created_at music_session.save(:validate => false) # 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(current_user, music_session, name, description, genre, language, musician_access, approval_required, fan_chat, fan_access, session_controller_id, friends_can_join) 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.friends_can_join = friends_can_join unless friends_can_join.nil? session_controller = User.find(session_controller_id) if session_controller_id.present? should_tick = music_session.set_session_controller(current_user, session_controller) music_session.save if should_tick && music_session.active_music_session music_session.active_music_session.tick_track_changes Notification.send_tracks_changed(music_session.active_music_session) end music_session end def participant_create(user, music_session_id, client_id, as_musician, tracks, audio_latency) connection = nil music_session = nil active_music_session = nil send_track_changed = false 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 send_track_changed = true 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 if send_track_changed Notification.send_tracks_changed(active_music_session) 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 tracks_changed = false 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 tracks_changed = true recording = active_music_session.stop_recording # stop any ongoing recording, if there is one recordingId = recording.id unless recording.nil? end end if tracks_changed Notification.send_tracks_changed(active_music_session) 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