From 432d391a32716932bade89fe37d522051d8525e7 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Fri, 11 Oct 2019 07:26:48 -0700 Subject: [PATCH] [memcached] goodbye Summary: Not used feature and with no obvious roadmap anymore. Reviewed By: jberdine, jvillard Differential Revision: D17855860 fbshipit-source-id: fd75b9d62 --- infer/man/man1/infer-full.txt | 7 -- infer/src/backend/InferAnalyze.ml | 6 +- infer/src/backend/Summary.ml | 8 -- infer/src/backend/Summary.mli | 4 - infer/src/backend/ondemand.ml | 51 +++------ infer/src/base/Config.ml | 14 --- infer/src/base/Config.mli | 4 - infer/src/base/Memcached.ml | 181 ------------------------------ infer/src/base/Memcached.mli | 39 ------- infer/src/infer.ml | 5 +- 10 files changed, 18 insertions(+), 301 deletions(-) delete mode 100644 infer/src/base/Memcached.ml delete mode 100644 infer/src/base/Memcached.mli diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 835880dc3..608ebb323 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -1479,13 +1479,6 @@ INTERNAL OPTIONS --max-nesting-reset Cancel the effect of --max-nesting. - --memcached - Activates: EXPERIMENTAL: Use memcached caching summaries during - analysis. (Conversely: --no-memcached) - - --memcached-size-mb int - EXPERIMENTAL: Default memcached size in megabytes. - --method-decls-info method_decls_info.json Specifies the file containing the method declarations info (eg. start line, end line, class, method name, etc.) when Infer is run diff --git a/infer/src/backend/InferAnalyze.ml b/infer/src/backend/InferAnalyze.ml index 6ca8cea47..23c59c5e0 100644 --- a/infer/src/backend/InferAnalyze.ml +++ b/infer/src/backend/InferAnalyze.ml @@ -42,16 +42,14 @@ let analyze_target : TaskScheduler.target Tasks.doer = Ondemand.analyze_proc_name_toplevel exe_env proc_name in fun target -> - if Config.memcached then Memcached.connect () ; let exe_env = Exe_env.mk () in (* clear cache for each source file to avoid it growing unboundedly *) clear_caches () ; - ( match target with + match target with | Procname procname -> analyze_proc_name exe_env procname | File source_file -> - analyze_source_file exe_env source_file ) ; - if Config.memcached then Memcached.disconnect () + analyze_source_file exe_env source_file let output_json_makefile_stats clusters = diff --git a/infer/src/backend/Summary.ml b/infer/src/backend/Summary.ml index beef797e4..6ae8b608c 100644 --- a/infer/src/backend/Summary.ml +++ b/infer/src/backend/Summary.ml @@ -288,11 +288,3 @@ module OnDisk = struct in Procedures.get_all ~filter () |> List.iter ~f:reset end - -module SummaryValue = struct - type nonrec t = t option - - let label = "summary" -end - -module SummaryServer = Memcached.Make (SummaryValue) diff --git a/infer/src/backend/Summary.mli b/infer/src/backend/Summary.mli index 64407a521..bba84bc11 100644 --- a/infer/src/backend/Summary.mli +++ b/infer/src/backend/Summary.mli @@ -120,7 +120,3 @@ module OnDisk : sig val dummy : t (** dummy summary for testing *) end - -module SummaryValue : Memcached.Value with type t = t option - -module SummaryServer : Memcached.Server with module Value = SummaryValue diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index db025d022..ce49ae98c 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -287,21 +287,6 @@ let create_perf_stats_report source_file = PerfStats.get_reporter (PerfStats.Backend source_file) () -let hash_procname proc_name = Typ.Procname.to_unique_id proc_name |> Utils.string_crc_hex32 - -let memcache_get proc_name = - if not Config.memcached then None - else - let key = hash_procname proc_name in - Summary.SummaryServer.get ~key - - -let memcache_set proc_name summ = - if Config.memcached then - let key = hash_procname proc_name in - Summary.SummaryServer.set ~key summ - - let register_callee ?caller_summary callee_pname = Option.iter ~f:(fun (summary : Summary.t) -> @@ -348,28 +333,22 @@ let analyze_callee ?caller_summary callee = | Some callee_summary_option -> callee_summary_option | None -> - let callee_summary_option, update_memcached = - match memcache_get callee_pname with - | Some summ_opt -> - (summ_opt, false) - | None -> - if callee_should_be_analyzed callee then - match get_callee_proc_desc callee with - | Some callee_pdesc -> - ( Some - (run_proc_analysis - ~caller_pdesc:(Option.map ~f:Summary.get_proc_desc caller_summary) - callee_pdesc) - , true ) - | None -> - (Summary.OnDisk.get callee_pname, true) - else ( - EventLogger.log_skipped_pname (F.asprintf "%a" Typ.Procname.pp callee_pname) ; - (Summary.OnDisk.get callee_pname, true) ) + let summ_opt = + if callee_should_be_analyzed callee then + match get_callee_proc_desc callee with + | Some callee_pdesc -> + Some + (run_proc_analysis + ~caller_pdesc:(Option.map ~f:Summary.get_proc_desc caller_summary) + callee_pdesc) + | None -> + Summary.OnDisk.get callee_pname + else ( + EventLogger.log_skipped_pname (F.asprintf "%a" Typ.Procname.pp callee_pname) ; + Summary.OnDisk.get callee_pname ) in - if update_memcached then memcache_set callee_pname callee_summary_option ; - LocalCache.add callee_pname callee_summary_option ; - callee_summary_option + LocalCache.add callee_pname summ_opt ; + summ_opt let analyze_proc_desc ~caller_summary callee_pdesc = diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index b95c81e1e..d028bd40c 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1738,16 +1738,6 @@ and method_decls_info = method name, etc.) when Infer is run Test Determinator mode with $(b,--test-determinator)." -and memcached = - CLOpt.mk_bool ~long:"memcached" ~default:false - "EXPERIMENTAL: Use memcached caching summaries during analysis." - - -and memcached_size_mb = - CLOpt.mk_int ~long:"memcached-size-mb" ~default:2048 - "EXPERIMENTAL: Default memcached size in megabytes." - - and merge = CLOpt.mk_bool ~deprecated:["merge"] ~long:"merge" ~in_help:InferCommand.[(Analyze, manual_buck_flavors)] @@ -2994,10 +2984,6 @@ and max_nesting = !max_nesting and method_decls_info = !method_decls_info -and memcached = !memcached - -and memcached_size_mb = !memcached_size_mb - and merge = !merge and ml_buckets = !ml_buckets diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 9e083333a..24df99b3d 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -481,10 +481,6 @@ val loop_hoisting : bool val max_nesting : int option -val memcached : bool - -val memcached_size_mb : int - val merge : bool val method_decls_info : string option diff --git a/infer/src/base/Memcached.ml b/infer/src/base/Memcached.ml deleted file mode 100644 index d24e66ace..000000000 --- a/infer/src/base/Memcached.ml +++ /dev/null @@ -1,181 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) -open! IStd -module L = Logging - -(** unix socket name, always relative to the master [results_dir] *) -let memcached_socket_relative = "memcached.socket" - -(** find the results_dir of the top-level infer process *) -let results_dir = Config.toplevel_results_dir - -(** log file for memcached *) -let memcached_log = results_dir ^ "/memcached.log" - -(** binary name -- assumed to be on path *) -let memcached_bin = "memcached" - -(** shell to use for redirecting memcached's output to the log *) -let shell = "sh" - -type server = {input: In_channel.t; output: Out_channel.t} - -(** Unix socket *paths* have a historical length limit of ~100 chars (!?*@&*$). However, this only applies - to the argument passed in the system call to create the socket, not to the actual path. - Thus a workaround is to cd into the parent dir of the socket and then use it, hence this function. *) -let in_results_dir ~f = Utils.do_in_dir ~dir:results_dir ~f - -let fail_on response_line = L.die InternalError "Unexpected server response: %s" response_line - -let send server str = Out_channel.output_string server.output str - -let eol = "\r\n" - -let send_eol server = send server eol - -let flush_server server = Out_channel.flush server.output - -let send_line server str = send server str ; send_eol server ; flush_server server - -let recv_line server = - match In_channel.input_line ~fix_win_eol:true server.input with - | None -> - fail_on "No response" - | Some line -> - line - - -let expect_line server lines = - match recv_line server with - | x when List.exists lines ~f:(String.equal x) -> - () - | response -> - fail_on response - - -(** socket to memcached server *) -let server : server option ref = ref None - -let with_server ~f = - match !server with - | None -> - L.die InternalError "Asked to perform socket operation without live connection.@." - | Some s -> - f s - - -let disconnect () = - with_server ~f:(fun s -> - server := None ; - Unix.shutdown_connection s.input ; - (* For some reason the below sometimes throws -- wrong docs? *) - (* In_channel.close s.input ; *) - Out_channel.close s.output ) - - -let connect () = - if Option.is_some !server then - L.die InternalError "Asked to connect memcached while already connected.@." ; - in_results_dir ~f:(fun () -> - let input, output = Unix.open_connection (ADDR_UNIX memcached_socket_relative) in - server := Some {input; output} ) - - -let stats server = - let rec aux acc = match recv_line server with "END" -> List.rev acc | l -> aux (l :: acc) in - send_line server "stats" ; aux [] - - -let stop pid () = - connect () ; - let stats = with_server ~f:stats in - disconnect () ; - Signal.send Signal.term (`Pid pid) |> ignore ; - Unix.wait (`Pid pid) |> ignore ; - in_results_dir ~f:(fun () -> Unix.remove memcached_socket_relative) ; - Out_channel.(with_file memcached_log ~append:true ~f:(fun ch -> output_lines ch stats)) - - -let start () = - let socket_exists () = - in_results_dir ~f:(fun () -> Sys.file_exists_exn memcached_socket_relative) - in - if Option.is_some !server then - L.die InternalError "Connection is open but asked to start memcached.@." ; - (* Unix sockets can be shadowed, so avoid creating a new socket/server if there is one already *) - if socket_exists () then () - else - let verbosity = match Config.debug_level_analysis with 0 -> "" | 1 -> "-v" | _ -> "-vv" in - let cmd = - Printf.sprintf "exec %s %s -Bascii -C -m%d -s%s > %s 2>&1" memcached_bin verbosity - Config.memcached_size_mb memcached_socket_relative memcached_log - in - let pid = in_results_dir ~f:(Unix.fork_exec ~prog:shell ~argv:[shell; "-c"; cmd]) in - (* Wait until socket is open -- NB this waits for 0.05s not 0.05ns *) - while not (socket_exists ()) do - Unix.nanosleep 0.05 |> ignore - done ; - Epilogues.register ~description:"Shutdown Memcached daemon" ~f:(stop pid) - - -module type Value = sig - type t - - val label : string -end - -module type Server = sig - module Value : Value - - val get : key:string -> Value.t option - - val set : key:string -> Value.t -> unit -end - -module Make (V : Value) : Server with module Value = V = struct - module Value = V - - let set_ = - let buffer = ref (Bytes.create 1024) in - let rec try_to_buffer value = - try Marshal.to_buffer !buffer 0 (Bytes.length !buffer) value [] - with Failure _ -> - (* double buffer length *) - buffer := Bytes.create (2 * Bytes.length !buffer) ; - try_to_buffer value - in - fun server ~key value -> - let value_length = try_to_buffer value in - Printf.fprintf server.output "set %s:%s 0 0 %d%s" Value.label key value_length eol ; - Out_channel.output server.output ~buf:!buffer ~pos:0 ~len:value_length ; - send_eol server ; - flush_server server ; - expect_line server ["STORED"; "SERVER_ERROR object too large for cache"] - - - let get_ server ~key = - Printf.fprintf server.output "get %s:%s%s" Value.label key eol ; - flush_server server ; - let value_line = recv_line server in - match String.split value_line ~on:' ' with - | ["END"] -> - None - | ["VALUE"; _key'; _flags; _bytes] -> - let value : Value.t = Marshal.from_channel server.input in - (* eat up the trailing eol *) - expect_line server [""] ; - expect_line server ["END"] ; - Some value - | _ -> - fail_on value_line - - - let get ~key = with_server ~f:(get_ ~key) - - (* TODO: do this on background thread to avoid blocking on the response *) - let set ~key value = with_server ~f:(fun s -> set_ s ~key value) -end diff --git a/infer/src/base/Memcached.mli b/infer/src/base/Memcached.mli deleted file mode 100644 index 544334513..000000000 --- a/infer/src/base/Memcached.mli +++ /dev/null @@ -1,39 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) -open! IStd - -(** Interface for managing a (single) memcached daemon and getting/setting OCaml values *) - -val connect : unit -> unit -(** connect to a running memcached server -- only call this from processes which do not fork *) - -val disconnect : unit -> unit -(** disconnect after having connected first *) - -val start : unit -> unit -(** start a memcached daemon and set up an epilogue to kill it on exit -- only for top-level *) - -(** type to marshal, plus a unique label that will be colon-prepended to a key, - roughly signifying a table *) -module type Value = sig - type t - - val label : string -end - -module type Server = sig - module Value : Value - - val get : key:string -> Value.t option - (** get a value, [None] means no [key] exists *) - - val set : key:string -> Value.t -> unit - (** set a [key]/value pair. NB we swallow failures due to exceeding max value size currently. - This will need to be changed before memcached is used as a primary store. *) -end - -module Make (V : Value) : Server with module Value = V diff --git a/infer/src/infer.ml b/infer/src/infer.ml index d0481a701..c904af5e9 100644 --- a/infer/src/infer.ml +++ b/infer/src/infer.ml @@ -63,10 +63,7 @@ let setup () = | Events -> ResultsDir.assert_results_dir "have you run infer before?" ) ; db_start () ; - if CLOpt.is_originator then ( - RunState.add_run_to_sequence () ; - RunState.store () ; - if Config.memcached then Memcached.start () ) ; + if CLOpt.is_originator then ( RunState.add_run_to_sequence () ; RunState.store () ) ; ()