temp.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include "temp.h"
  2. #include "errors.h"
  3. #include <yt/cpp/mapreduce/interface/config.h>
  4. #include <util/system/yassert.h>
  5. namespace NYT {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. TTempTable::TTempTable(
  8. IClientBasePtr client,
  9. const TString& prefix,
  10. const TYPath& directory,
  11. const TCreateOptions& options)
  12. : Client_(std::move(client))
  13. {
  14. Name_ = CreateTempTable(Client_, prefix, directory, options);
  15. }
  16. TTempTable::TTempTable(TTempTable::TPrivateConstuctorTag, IClientBasePtr client, TYPath path, const TCreateOptions& options)
  17. : Client_(std::move(client))
  18. , Name_(std::move(path))
  19. {
  20. Client_->Create(Name_, NT_TABLE, options);
  21. }
  22. TTempTable::TTempTable(TTempTable&& sourceTable)
  23. : Client_(sourceTable.Client_)
  24. , Name_(sourceTable.Name_)
  25. , Owns_(sourceTable.Owns_)
  26. {
  27. sourceTable.Owns_ = false;
  28. }
  29. TTempTable& TTempTable::operator=(TTempTable&& sourceTable)
  30. {
  31. if (&sourceTable == this) {
  32. return *this;
  33. }
  34. if (Owns_) {
  35. RemoveTable();
  36. }
  37. Client_ = sourceTable.Client_;
  38. Name_ = sourceTable.Name_;
  39. Owns_ = sourceTable.Owns_;
  40. sourceTable.Owns_ = false;
  41. return *this;
  42. }
  43. TTempTable TTempTable::CreateAutoremovingTable(IClientBasePtr client, TYPath path, const TCreateOptions& options)
  44. {
  45. return TTempTable(TTempTable::TPrivateConstuctorTag(), std::move(client), std::move(path), options);
  46. }
  47. void TTempTable::RemoveTable()
  48. {
  49. if (TConfig::Get()->KeepTempTables) {
  50. return;
  51. }
  52. Client_->Remove(Name_, TRemoveOptions().Force(true));
  53. }
  54. TTempTable::~TTempTable()
  55. {
  56. if (Owns_) {
  57. try {
  58. RemoveTable();
  59. } catch (...) {
  60. }
  61. }
  62. }
  63. TString TTempTable::Name() const &
  64. {
  65. return Name_;
  66. }
  67. TString TTempTable::Release()
  68. {
  69. Y_ASSERT(Owns_);
  70. Owns_ = false;
  71. return Name_;
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////
  74. TYPath CreateTempTable(
  75. const IClientBasePtr& client,
  76. const TString& prefix,
  77. const TYPath& directory,
  78. const TCreateOptions& options)
  79. {
  80. TYPath result;
  81. bool createDirectory = false;
  82. if (directory) {
  83. result = directory;
  84. } else {
  85. result = TConfig::Get()->RemoteTempTablesDirectory;
  86. // User might override configuration above.
  87. // Class used to create directory in such cases if it doesn't exist.
  88. // We keep this behaviour.
  89. createDirectory = true;
  90. }
  91. if (result == DefaultRemoteTempTablesDirectory) {
  92. result += "/";
  93. result += client->GetParentClient()->WhoAmI().Login;
  94. createDirectory = true;
  95. }
  96. auto resultDirectory = result;
  97. result += "/";
  98. result += prefix;
  99. result += CreateGuidAsString();
  100. if (!createDirectory) {
  101. client->Create(result, NT_TABLE, options);
  102. } else {
  103. // Directory we are going to create our table in can be missing.
  104. // We create it explicitly outside of any transactions,
  105. // because concurrent processes might want to create the same directory from other transactions.
  106. //
  107. // It's unlikely but directory might be removed between directory creation and table creation
  108. // we retry attempt if it was failed with path resolution error.
  109. const int maxAttempts = 3;
  110. for (int i = 0; i < maxAttempts; ++i) {
  111. client->GetParentClient()->Create(resultDirectory, NT_MAP, TCreateOptions().Recursive(true).IgnoreExisting(true));
  112. try {
  113. client->Create(result, NT_TABLE, options);
  114. break;
  115. } catch (const TErrorResponse& error) {
  116. if (error.IsResolveError()) {
  117. if (i < maxAttempts - 1) {
  118. continue;
  119. }
  120. }
  121. throw;
  122. }
  123. }
  124. }
  125. return result;
  126. }
  127. ////////////////////////////////////////////////////////////////////////////////
  128. } // namespace NYT