From cebbd869cbbfcaa7ba5a62ddfce3430800485c38 Mon Sep 17 00:00:00 2001 From: Bert Owen Date: Tue, 20 May 2014 21:26:32 +0800 Subject: [PATCH] VRFS-1675 add join session feature --- .../jam_ruby/models/active_music_session.rb | 99 +++++++++++++++++++ web/app/assets/javascripts/jam_rest.js | 14 +++ web/app/assets/javascripts/sessionModel.js | 2 +- .../api_music_sessions_controller.rb | 28 ++++++ web/config/routes.rb | 1 + 5 files changed, 143 insertions(+), 1 deletion(-) diff --git a/ruby/lib/jam_ruby/models/active_music_session.rb b/ruby/lib/jam_ruby/models/active_music_session.rb index 248879bbc..6acfacc88 100644 --- a/ruby/lib/jam_ruby/models/active_music_session.rb +++ b/ruby/lib/jam_ruby/models/active_music_session.rb @@ -314,6 +314,105 @@ module JamRuby return query end + def self.participant_create user, music_session_id, client_id, as_musician, tracks + music_session = MusicSession.find(music_session_id) + + if music_session.active_music_session + connection = nil + active_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) + + 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) + + # 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(active_music_session, user) + end + end + end + + connection + else + 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 music_session.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 music_session.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) + + 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 music_session.band.nil? + Notification.send_band_session_join(active_music_session, 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 + Logging.logger[self].warn "creating a music session took #{time*1000} milliseconds" + end + + return_value + end + end + # Verifies that the specified user can join this music session def can_join? user, as_musician if as_musician diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index b386447c3..0ffc575a8 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -59,6 +59,19 @@ }); } + function joinSession(options) { + var sessionId = options["session_id"]; + delete options["session_id"]; + + return $.ajax({ + type: "POST", + dataType: "json", + contentType: 'application/json', + url: "/api/sessions/" + sessionId + "/participants", + processData: false + }); + } + function findSessions(query) { return $.ajax({ type: "GET", @@ -1007,6 +1020,7 @@ this.initialize = initialize; this.legacyCreateSession = legacyCreateSession; this.legacyJoinSession = legacyJoinSession; + this.joinSession = joinSession; this.getUserDetail = getUserDetail; this.getCities = getCities; this.getRegions = getRegions; diff --git a/web/app/assets/javascripts/sessionModel.js b/web/app/assets/javascripts/sessionModel.js index 791503e06..1f40a3818 100644 --- a/web/app/assets/javascripts/sessionModel.js +++ b/web/app/assets/javascripts/sessionModel.js @@ -365,7 +365,7 @@ session_id: sessionId }; - return rest.legacyJoinSession(data); + return rest.joinSession(data); } function leaveSessionRest(sessionId) { diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb index 300d67e11..64c14a9ec 100644 --- a/web/app/controllers/api_music_sessions_controller.rb +++ b/web/app/controllers/api_music_sessions_controller.rb @@ -180,6 +180,34 @@ class ApiMusicSessionsController < ApiController end end + def participant_create + client_id = params[:client_id] + + if client_id.nil? + raise JamArgumentError, "client_id must be specified" + end + + begin + @connection = ActiveMusicSession.participant_create( + current_user, + params[:id], + params[:client_id], + params[:as_musician], + params[:tracks] + ) + + if @connection.errors.any? + response.status = :unprocessable_entity + respond_with @connection + else + respond_with @connection, responder: ApiResponder, :location => api_session_participant_detail_url(@connection.client_id) + end + + rescue ActiveRecord::RecordNotFound + render :json => { :message => ValidationMessages::SESSION_NOT_FOUND }, :status => 404 + end + end + def participant_delete client_id = params[:id] if client_id.present? && client_id != 'undefined' diff --git a/web/config/routes.rb b/web/config/routes.rb index 8be884f76..e5fe264e2 100644 --- a/web/config/routes.rb +++ b/web/config/routes.rb @@ -145,6 +145,7 @@ SampleApp::Application.routes.draw do # music sessions match '/sessions/:id/participants/legacy' => 'api_music_sessions#participant_create_legacy', :via => :post # can be removed when new Create Session comes in + match '/sessions/:id/participants' => 'api_music_sesssions#participant_create', :via => :post match '/participants/:id' => 'api_music_sessions#participant_show', :via => :get, :as => 'api_session_participant_detail' match '/participants/:id' => 'api_music_sessions#participant_delete', :via => :delete match '/sessions/:id' => 'api_music_sessions#show', :via => :get, :as => 'api_session_detail'