TODO(bevers): Add a query parameter to select json or html format. TODO(bevers): Add a query parameter to configure the sampling interval.
| 657 | // TODO(bevers): Add a query parameter to select json or html format. |
| 658 | // TODO(bevers): Add a query parameter to configure the sampling interval. |
| 659 | Future<http::Response> MemoryProfiler::start( |
| 660 | const http::Request& request, |
| 661 | const Option<http::authentication::Principal>&) |
| 662 | { |
| 663 | if (!detectJemalloc()) { |
| 664 | return http::BadRequest(string(JEMALLOC_NOT_DETECTED_MESSAGE) + ".\n"); |
| 665 | } |
| 666 | |
| 667 | Duration duration = DEFAULT_COLLECTION_TIME; |
| 668 | |
| 669 | // TODO(bevers): Introduce `http::Request::extractQueryParameter<T>(string)` |
| 670 | // instead of doing it ad-hoc here. |
| 671 | Option<string> durationParameter = request.url.query.get("duration"); |
| 672 | if (durationParameter.isSome()) { |
| 673 | Try<Duration> parsed = Duration::parse(durationParameter.get()); |
| 674 | if (parsed.isError()) { |
| 675 | return http::BadRequest( |
| 676 | "Could not parse parameter 'duration': " + parsed.error() + ".\n"); |
| 677 | } |
| 678 | duration = parsed.get(); |
| 679 | } |
| 680 | |
| 681 | if (duration < MINIMUM_COLLECTION_TIME || |
| 682 | duration > MAXIMUM_COLLECTION_TIME) { |
| 683 | return http::BadRequest( |
| 684 | "Duration '" + stringify(duration) + "' must be between " |
| 685 | + stringify(MINIMUM_COLLECTION_TIME) + " and " |
| 686 | + stringify(MAXIMUM_COLLECTION_TIME) + ".\n"); |
| 687 | } |
| 688 | |
| 689 | Try<bool> wasActive = jemalloc::startProfiling(); |
| 690 | if (wasActive.isError()) { |
| 691 | return http::BadRequest( |
| 692 | string(JEMALLOC_PROFILING_NOT_ENABLED_MESSAGE) + ".\n"); |
| 693 | } |
| 694 | |
| 695 | if (!wasActive.get()) { |
| 696 | time_t id = std::chrono::system_clock::to_time_t( |
| 697 | std::chrono::system_clock::now()); |
| 698 | currentRun = ProfilingRun(this, id, duration); |
| 699 | } |
| 700 | |
| 701 | JSON::Object response; |
| 702 | |
| 703 | // This can happen when jemalloc was configured e.g. via the `MALLOC_CONF` |
| 704 | // environment variable. We don't touch it in this case. |
| 705 | if (!currentRun.isSome()) { |
| 706 | return http::Conflict("Heap profiling was started externally.\n"); |
| 707 | } |
| 708 | |
| 709 | string message = wasActive.get() ? |
| 710 | "Heap profiling is already active." : |
| 711 | "Successfully started new heap profiling run."; |
| 712 | |
| 713 | message += |
| 714 | " After the remaining time elapses, download the generated profile at '/" + |
| 715 | this->self().id + "/download/raw?id=" + stringify(currentRun->id) + "'." + |
| 716 | " Visit '/" + this->self().id + "/stop' to stop collection earlier."; |
nothing calls this directly
no test coverage detected