| 259 | |
| 260 | |
| 261 | DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_reason, const ZooKeeperPtr & zookeeper) |
| 262 | { |
| 263 | String node_data; |
| 264 | String entry_path = fs::path(queue_dir) / entry_name; |
| 265 | |
| 266 | auto task = std::make_unique<DDLTask>(entry_name, entry_path); |
| 267 | |
| 268 | if (!zookeeper->tryGet(entry_path, node_data)) |
| 269 | { |
| 270 | /// It is Ok that node could be deleted just now. It means that there are no current host in node's host list. |
| 271 | out_reason = "The task was deleted"; |
| 272 | return {}; |
| 273 | } |
| 274 | |
| 275 | auto write_error_status = [&](const String & host_id, const String & error_message, const String & reason) |
| 276 | { |
| 277 | LOG_ERROR(log, "Cannot parse DDL task {}: {}. Will try to send error status: {}", entry_name, reason, error_message); |
| 278 | createStatusDirs(entry_path, zookeeper); |
| 279 | zookeeper->tryCreate(fs::path(entry_path) / "finished" / host_id, error_message, zkutil::CreateMode::Persistent); |
| 280 | }; |
| 281 | |
| 282 | try |
| 283 | { |
| 284 | /// Stage 1: parse entry |
| 285 | task->entry.parse(node_data); |
| 286 | } |
| 287 | catch (...) |
| 288 | { |
| 289 | /// What should we do if we even cannot parse host name and therefore cannot properly submit execution status? |
| 290 | /// We can try to create fail node using FQDN if it equal to host name in cluster config attempt will be successful. |
| 291 | /// Otherwise, that node will be ignored by DDLQueryStatusInputStream. |
| 292 | out_reason = "Incorrect task format"; |
| 293 | write_error_status(host_fqdn_id, ExecutionStatus::fromCurrentException().serializeText(), out_reason); |
| 294 | return {}; |
| 295 | } |
| 296 | |
| 297 | /// Stage 2: resolve host_id and check if we should execute query or not |
| 298 | /// Multiple clusters can use single DDL queue path in ZooKeeper, |
| 299 | /// So we should skip task if we cannot find current host in cluster hosts list. |
| 300 | if (!task->findCurrentHostID(context, log)) |
| 301 | { |
| 302 | out_reason = "There is no a local address in host list"; |
| 303 | return {}; |
| 304 | } |
| 305 | |
| 306 | try |
| 307 | { |
| 308 | /// Stage 3.1: parse query |
| 309 | task->parseQueryFromEntry(context); |
| 310 | /// Stage 3.2: check cluster and find the host in cluster |
| 311 | task->setClusterInfo(context, log); |
| 312 | /// Stage 3.3: output rewritten query back to string |
| 313 | task->formatRewrittenQuery(context); |
| 314 | } |
| 315 | catch (...) |
| 316 | { |
| 317 | out_reason = "Cannot parse query or obtain cluster info"; |
| 318 | write_error_status(task->host_id_str, ExecutionStatus::fromCurrentException().serializeText(), out_reason); |
nothing calls this directly
no test coverage detected