From 5a749c79773fa327dffb6550b2a4206bee2857bb Mon Sep 17 00:00:00 2001 From: fgerlits Date: Sat, 15 Jan 2005 12:07:09 +0000 Subject: [PATCH] modified the WebStorageClient to keep a cache of the playlists which are currently being edited --- .../modules/storage/src/TestStorageClient.cxx | 8 +++-- .../modules/storage/src/WebStorageClient.cxx | 29 +++++++++++++++++-- .../modules/storage/src/WebStorageClient.h | 29 +++++++++++++++++-- .../storage/src/WebStorageClientTest.cxx | 18 ++++++++++-- 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/livesupport/modules/storage/src/TestStorageClient.cxx b/livesupport/modules/storage/src/TestStorageClient.cxx index ad9cd07dd..01ea2e158 100644 --- a/livesupport/modules/storage/src/TestStorageClient.cxx +++ b/livesupport/modules/storage/src/TestStorageClient.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.30 $ + Version : $Revision: 1.31 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -300,17 +300,19 @@ TestStorageClient :: savePlaylist(Ptr::Ref sessionId, editIt = editedPlaylists.find(playlist->getId()->getId()); if ((editIt == editedPlaylists.end()) - || (*playlist->getToken() != *editIt->second->getToken())) { + || (*playlist->getToken() != *editIt->second->getToken())) { throw XmlRpcException("savePlaylist() called without editPlaylist()"); } + Ptr::Ref nullPointer; + playlist->setToken(nullPointer); + PlaylistMapType::iterator storeIt = playlistMap.find(playlist->getId()->getId()); if (storeIt == playlistMap.end()) { throw XmlRpcException("playlist deleted while it was being edited???"); } - storeIt->second = playlist; editedPlaylists.erase(editIt); diff --git a/livesupport/modules/storage/src/WebStorageClient.cxx b/livesupport/modules/storage/src/WebStorageClient.cxx index bab85d76c..734010f6b 100644 --- a/livesupport/modules/storage/src/WebStorageClient.cxx +++ b/livesupport/modules/storage/src/WebStorageClient.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.26 $ + Version : $Revision: 1.27 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -693,6 +693,14 @@ WebStorageClient :: getPlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (Core::XmlRpcException) { + EditedPlaylistsType::const_iterator + editIt = editedPlaylists.find(id->getId()); + + if (editIt != editedPlaylists.end() // is being edited + && (*editIt->second.first == *sessionId)) { // by us + return editIt->second.second; + } + XmlRpcValue parameters; XmlRpcValue result; @@ -808,11 +816,16 @@ WebStorageClient :: editPlaylist(Ptr::Ref sessionId, Ptr::Ref id) throw (Core::XmlRpcException) { - Ptr::Ref playlist(new Playlist(id)); + if (editedPlaylists.find(id->getId()) != editedPlaylists.end()) { + throw XmlRpcInvalidArgumentException("playlist is already" + " being edited"); + } + Ptr::Ref url, token; editPlaylistGetUrl(sessionId, id, url, token); + Ptr::Ref playlist(new Playlist(id)); try { Ptr::Ref parser(new xmlpp::DomParser()); parser->parse_file(*url); @@ -830,6 +843,7 @@ WebStorageClient :: editPlaylist(Ptr::Ref sessionId, } playlist->setToken(token); + editedPlaylists[id->getId()] = std::make_pair(sessionId, playlist); return playlist; } @@ -905,6 +919,16 @@ WebStorageClient :: savePlaylist(Ptr::Ref sessionId, throw XmlRpcInvalidArgumentException("playlist has no token field"); } + EditedPlaylistsType::iterator + editIt = editedPlaylists.find(playlist->getId()->getId()); + + if ((editIt == editedPlaylists.end()) + || *editIt->second.first != *sessionId) { + throw XmlRpcInvalidArgumentException("savePlaylist() called without " + "editPlaylist()"); + } + editedPlaylists.erase(editIt); + XmlRpcValue parameters; XmlRpcValue result; @@ -1238,6 +1262,7 @@ WebStorageClient :: createPlaylist(Ptr::Ref sessionId) Ptr::Ref playlist(new Playlist(newId, playlength)); playlist->setToken(token); + editedPlaylists[newId->getId()] = std::make_pair(sessionId, playlist); savePlaylist(sessionId, playlist); token.reset(); diff --git a/livesupport/modules/storage/src/WebStorageClient.h b/livesupport/modules/storage/src/WebStorageClient.h index 24b516c47..a485828fa 100644 --- a/livesupport/modules/storage/src/WebStorageClient.h +++ b/livesupport/modules/storage/src/WebStorageClient.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.18 $ + Version : $Revision: 1.19 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.h,v $ ------------------------------------------------------------------------------*/ @@ -99,7 +99,7 @@ using namespace LiveSupport::Core; * * * @author $Author: fgerlits $ - * @version $Revision: 1.18 $ + * @version $Revision: 1.19 $ */ class WebStorageClient : virtual public Configurable, @@ -131,6 +131,18 @@ class WebStorageClient : */ std::string storageServerPath; + /** + * The type for the list of playlists which are currently being edited + */ + typedef std::map::Ref, Ptr::Ref> > + EditedPlaylistsType; + + /** + * The list of playlists which are currently being edited + */ + EditedPlaylistsType editedPlaylists; + /** * Auxilliary method used by editPlaylist() and createPlaylist(). * Opens the playlist for editing, and returns its URL. @@ -215,7 +227,12 @@ class WebStorageClient : /** * Return a playlist with the specified id to be displayed. - * If the playlist is being edited, its last saved state is returned. + * If the playlist is being edited, and this method is called + * by the same user who is editing the playlist, + * (i.e., the method is called with the same sessionId and playlistId + * that editPlaylist() was), then the working copy of the playlist + * is returned. + * Any other user gets the old (pre-editPlaylist()) copy from storage. * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -235,6 +252,10 @@ class WebStorageClient : * This puts a lock on the playlist, and nobody else can edit it * until we release it using savePlaylist(). * + * This method creates a working copy of the playlist, which will + * be returned by getPlaylist() if it is called with the same + * sessionId and playlistId, until we call savePlaylist(). + * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. * @return the requested playlist. @@ -252,6 +273,8 @@ class WebStorageClient : * Can only be called after we obtained a lock on the playlist using * editPlaylist(); this method releases the lock. * + * This method destroys the working copy created by editPlaylist(). + * * @param sessionId the session ID from the authentication client * @param playlist the playlist to save. * @exception XmlRpcException if there is a problem with the XML-RPC diff --git a/livesupport/modules/storage/src/WebStorageClientTest.cxx b/livesupport/modules/storage/src/WebStorageClientTest.cxx index db0f29095..3508e5242 100644 --- a/livesupport/modules/storage/src/WebStorageClientTest.cxx +++ b/livesupport/modules/storage/src/WebStorageClientTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.28 $ + Version : $Revision: 1.29 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -239,7 +239,7 @@ WebStorageClientTest :: playlistTest(void) try { playlist = wsc->editPlaylist(sessionId, playlistIdxx); CPPUNIT_FAIL("allowed to open playlist for editing twice"); - } catch (Core::XmlRpcMethodFaultException &e) { + } catch (Core::XmlRpcInvalidArgumentException &e) { } catch (XmlRpcException &e) { std::string eMsg = "editPlaylist() threw unexpected exception:\n"; CPPUNIT_FAIL(eMsg + e.what()); @@ -265,9 +265,21 @@ WebStorageClientTest :: playlistTest(void) try { Ptr::Ref throwAwayPlaylist = wsc->getPlaylist(sessionId, playlistIdxx); - // this should be OK, get old copy + // we are editing it, get another working copy + CPPUNIT_ASSERT(throwAwayPlaylist->getPlaylength() + ->total_seconds() == 9); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } + + try { + Ptr::Ref newSessionId = authentication->login("root", "q"); + Ptr::Ref throwAwayPlaylist + = wsc->getPlaylist(newSessionId, playlistIdxx); + // somebody else is editing it, get the old copy CPPUNIT_ASSERT(throwAwayPlaylist->getPlaylength() ->total_seconds() == 0); + authentication->logout(newSessionId); } catch (XmlRpcException &e) { CPPUNIT_FAIL(e.what()); }