PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/MalApi/RateLimitingMyAnimeListApi.cs

https://bitbucket.org/LHCGreg/mal-api
C# | 133 lines | 102 code | 10 blank | 21 comment | 8 complexity | ec886bb5156c0963d97969dbade38ef2 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6. using System.Threading;
  7. namespace MalApi
  8. {
  9. /// <summary>
  10. /// Limits MAL requests by waiting a given time period betwen each request.
  11. /// The time is measured from before one request is made to before the next request is made.
  12. /// You might use this to be nice to MAL and avoid making requests as fast as possible.
  13. /// This class is thread-safe if the underlying API is.
  14. /// </summary>
  15. public class RateLimitingMyAnimeListApi : IMyAnimeListApi
  16. {
  17. private IMyAnimeListApi m_underlyingApi;
  18. private bool m_ownApi;
  19. public TimeSpan TimeBetweenRequests { get; private set; }
  20. private Stopwatch m_stopwatchStartedAtLastRequest = null;
  21. private object m_syncHandle = new object();
  22. public RateLimitingMyAnimeListApi(IMyAnimeListApi underlyingApi, TimeSpan timeBetweenRequests, bool ownApi = false)
  23. {
  24. m_underlyingApi = underlyingApi;
  25. TimeBetweenRequests = timeBetweenRequests;
  26. m_ownApi = ownApi;
  27. }
  28. private void SleepIfNeeded()
  29. {
  30. lock (m_syncHandle)
  31. {
  32. if (m_stopwatchStartedAtLastRequest != null)
  33. {
  34. TimeSpan timeSinceLastRequest = m_stopwatchStartedAtLastRequest.Elapsed;
  35. if (timeSinceLastRequest < TimeBetweenRequests)
  36. {
  37. TimeSpan timeToWait = TimeBetweenRequests - timeSinceLastRequest;
  38. Logging.Log.InfoFormat("Waiting {0} before making request.", timeToWait);
  39. Thread.Sleep(timeToWait);
  40. }
  41. }
  42. }
  43. }
  44. private void SetStopwatch()
  45. {
  46. lock (m_syncHandle)
  47. {
  48. if (m_stopwatchStartedAtLastRequest == null)
  49. {
  50. m_stopwatchStartedAtLastRequest = new Stopwatch();
  51. }
  52. m_stopwatchStartedAtLastRequest.Restart();
  53. }
  54. }
  55. public MalUserLookupResults GetAnimeListForUser(string user)
  56. {
  57. lock (m_syncHandle)
  58. {
  59. SleepIfNeeded();
  60. try
  61. {
  62. return m_underlyingApi.GetAnimeListForUser(user);
  63. }
  64. finally
  65. {
  66. SetStopwatch();
  67. }
  68. }
  69. }
  70. public RecentUsersResults GetRecentOnlineUsers()
  71. {
  72. lock (m_syncHandle)
  73. {
  74. SleepIfNeeded();
  75. try
  76. {
  77. return m_underlyingApi.GetRecentOnlineUsers();
  78. }
  79. finally
  80. {
  81. SetStopwatch();
  82. }
  83. }
  84. }
  85. public AnimeDetailsResults GetAnimeDetails(int animeId)
  86. {
  87. lock (m_syncHandle)
  88. {
  89. SleepIfNeeded();
  90. try
  91. {
  92. return m_underlyingApi.GetAnimeDetails(animeId);
  93. }
  94. finally
  95. {
  96. SetStopwatch();
  97. }
  98. }
  99. }
  100. public void Dispose()
  101. {
  102. if (m_ownApi && m_underlyingApi != null)
  103. {
  104. m_underlyingApi.Dispose();
  105. }
  106. }
  107. }
  108. }
  109. /*
  110. Copyright 2012 Greg Najda
  111. Licensed under the Apache License, Version 2.0 (the "License");
  112. you may not use this file except in compliance with the License.
  113. You may obtain a copy of the License at
  114. http://www.apache.org/licenses/LICENSE-2.0
  115. Unless required by applicable law or agreed to in writing, software
  116. distributed under the License is distributed on an "AS IS" BASIS,
  117. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  118. See the License for the specific language governing permissions and
  119. limitations under the License.
  120. */