A two-step optimization technique for functions placement, partitioning, and priority assignment in distributed systems